Ajude-me a gerenciar meu tempo

15

Recentemente, fui instruído a ler um livro inteiro de física até o ano novo (história verdadeira, infelizmente). Preciso da sua ajuda para determinar quais capítulos devo ler todos os dias. É aqui que você entra.

Entrada

  • Duas datas, em qualquer formato. A segunda data será sempre posterior à primeira.
  • Uma lista de números de capítulo. Essa lista separada por vírgula pode conter capítulos únicos ( 12) ou intervalos inclusivos ( 1-3). Ex. 1-3,5,6,10-13.
  • Uma lista de dias da semana (representada pelas duas primeiras letras do nome Monday -> Mo:) a serem excluídas da programação. Ex. Mo,Tu,Fr.

Resultado

A saída será uma lista separada por nova linha de datas e números de capítulos (veja o formato abaixo). Os capítulos devem ser distribuídos uniformemente por todos os dias no intervalo, excluindo os dias da semana fornecidos. Se os capítulos não distribuírem uniformemente, tenha os dias com quantidades menores de capítulos no final do período. As datas na saída podem estar em um formato diferente da entrada. Dias sem capítulos podem ser omitidos ou simplesmente não têm capítulos.

Exemplo:

Entrada: 9/17/2015 9/27/2015 1-15 Tu

Resultado:

9/17/2015: 1 2
9/18/2015: 3 4
9/19/2015: 5 6
9/20/2015: 7 8
9/21/2015: 9 10
9/23/2015: 11
9/24/2015: 12
9/25/2015: 13
9/26/2015: 14
9/27/2015: 15
GamrCorps
fonte
A entrada no exemplo deve ser `17/9/2015 27/9/2015 1-15 Tu 'porque 22/9 é uma terça-feira.
21415
@DavidCarraher você está certo, quando fiz essa amostra de entrada, eu estava pensando em novembro por algum motivo.
GamrCorps
7
Se fosse eu a última data teria todos os capítulos :)
MickyT
@MickyT precisamente minha inspiração para este desafio.
GamrCorps
Você logo descobrirá o quanto a física é incrível. Você tem sorte, na verdade.
Fabrizio Calderan

Respostas:

2

PowerShell v4, 367 357 323 313 308 307 305 277 bytes

param($a,$b,$c,$d)$e=@();$c=-split('('+($c-replace'-','..'-replace',','),(')+')'|iex|%{$_-join' '});while($a-le$b){if(-join"$($a.DayOfWeek)"[0,1]-notin$d){$e+=$a;$z++}$a=$a.AddDays(1)}$g=,0*$z;$c|%{$g[$c.IndexOf($_)%$z]++};1..$z|%{"$($e[$_-1]): "+$c[$i..($i+=$g[$_-1]-1)];$i++}

Editar - jogou 28 bytes usando formatação explícita de entrada.

Explicado:

param($a,$b,$c,$d)    # Parameters, takes our four inputs
$e=@()                # This is our array of valid output dates

$c=-split('('+($c-replace'-','..'-replace',','),(')+')'|iex|%{$_-join' '})
# Ridiculously complex way to turn the input chapters into an int array
# The first part changes "1,5-9,12" into a "(1),(5..9),(12)" format that
# PowerShell understands, then executes that with iex, which creates an 
# array of arrays. Then iterate through each inner array and joins them all
# together with spaces, then finally splits on spaces to create a 1D array

while($a-le$b){       # Until we reach the end day
  if(-join"$($a.DayOfWeek)"[0,1]-notin$d){
    # Not an excluded day of the week
    $e+=$a            # Add it to our list of days
    $z++              # Increment our count of total days
  }
  $a=$a.AddDays(1)    # Move to the next day in the range
}

$g=,0*$z              # Populate a new array with zeroes, same length as $e

$c|%{$g[$c.IndexOf($_)%$z]++}
# This populates $g for how many chapters we need each day

1..$z|%{"$($e[$_-1]): "+$c[$i..($i+=$g[$_-1]-1)];$i++}
# Goes through the days in $e, prints them, and slices $c based on $g

Uso

Espera que as datas estejam no DateTimeformato .NET . Espera que os dias "ignorados" estejam em uma matriz (equivalente ao PowerShell a uma lista).

PS C:\Tools\Scripts\golfing> .\help-me-manage-my-time.ps1 (Get-Date '9/17/2015') (Get-Date '9/27/2015') '5,1-3,6,10-13,20-27' @('Su','Tu')
09/17/2015 00:00:00: 5 1 2
09/18/2015 00:00:00: 3 6
09/19/2015 00:00:00: 10 11
09/21/2015 00:00:00: 12 13
09/23/2015 00:00:00: 20 21
09/24/2015 00:00:00: 22 23
09/25/2015 00:00:00: 24 25
09/26/2015 00:00:00: 26 27
AdmBorkBork
fonte
3
Há tantos cifrões aqui ... Isso deve ser caro! : D
kirbyfan64sos
@ kirbyfan64sos Apenas 12% dos personagens aqui são $... Na verdade, essa é uma média bastante média para os jogadores do PowerShell, que parece estar entre 10% e 15% (com base nos meus próprios cálculos informais de respostas que eu postei).
AdmBorkBork
Mais uma vez para você :-)
Willem
Hmm 308 para o meu bem ...
Willem
Bom trabalho em 305! Agora, 300 :-)
Willem
3

JavaScript (ES6), 317 310 291 bytes

(a,b,c,d)=>{u=0;c.split`,`.map(m=>{p=m[s]`-`;for(q=n=p[0];n<=(p[1]||q);r=++u)c+=","+n++},c="");c=c.split`,`;x=d.map(p=>"SuMoTuWeThFrSa".search(p)/2);for(g=[];a<b;a.setTime(+a+864e5))x.indexOf(a.getDay())<0&&(t=y=g.push(a+" "));return g.map(w=>w+c.slice(u-r+1,u-(r-=r/y--+.99|0)+1)).join`
`}

Uso

f(new Date("2015-09-17"),new Date("2015-09-27"),"5,1-4,6,10-13,20-27",["Su","Tu"])
=> "Thu Sep 17 2015 10:00:00 GMT+1000 (AUS Eastern Standard Time) 5,1,2
Fri Sep 18 2015 10:00:00 GMT+1000 (AUS Eastern Standard Time) 3,4,6
Sat Sep 19 2015 10:00:00 GMT+1000 (AUS Eastern Standard Time) 10,11
Mon Sep 21 2015 10:00:00 GMT+1000 (AUS Eastern Standard Time) 12,13
Wed Sep 23 2015 10:00:00 GMT+1000 (AUS Eastern Standard Time) 20,21
Thu Sep 24 2015 10:00:00 GMT+1000 (AUS Eastern Standard Time) 22,23
Fri Sep 25 2015 10:00:00 GMT+1000 (AUS Eastern Standard Time) 24,25
Sat Sep 26 2015 10:00:00 GMT+1000 (AUS Eastern Standard Time) 26,27"

Explicação

(a,b,c,d)=>{

  u=0;                                                 // u = total chapters
  c.split`,`.map(m=>{                                  // c = array of each chapter
    p=m[s]`-`;
    for(q=n=p[0];n<=(p[1]||q);r=++u)                   // get each chapter from ranges
      c+=","+n++
  },c="");
  c=c.split`,`;

  x=d.map(p=>"SuMoTuWeThFrSa".search(p)/2);            // x = days to skip
  for(g=[];a<b;a.setTime(+a+864e5))                    // for each day between a and b
    x.indexOf(a.getDay())<0&&                          // if this day is not skipped
      (t=y=g.push(a+" "));                             // add it to the list of days
                                                       // t = total days
                                                       // y = days remaining

  return g.map(w=>w+
    c.slice(u-r+1,u-(r-=r/y--+.99|0)+1)                // add the chapters of the day
  ).join`
`
}
user81655
fonte
2

Python 2 - 338 317 308 304 300

Aqui vamos fazer a bola rolar ...

def f(a,b,c,d):
 from pandas import*;import numpy as n
 s=str.split;e=n.array([])
 for g in s(c,','):h=s(g,'-');e=n.append(e,range(int(h[0]),int(h[-1])+1))
 k=[t for t in date_range(a,b) if s('Mo Tu We Th Fr Sa Su')[t.weekday()]not in d];j=len(k);e=array_split(e,j)
 for u in range(j):print k[u],e[u]

Exemplo de entrada:

f('9/17/2015','9/27/2015','5,1-3,6,10-13,20-27',['Su','Tu'])

Saída de exemplo:

2015-09-17 00:00:00 [ 5.  1.  2.]
2015-09-18 00:00:00 [ 3.  6.]
2015-09-19 00:00:00 [ 10.  11.]
2015-09-21 00:00:00 [ 12.  13.]
2015-09-23 00:00:00 [ 20.  21.]
2015-09-24 00:00:00 [ 22.  23.]
2015-09-25 00:00:00 [ 24.  25.]
2015-09-26 00:00:00 [ 26.  27.]
Willem
fonte