Hoje é o centro

36

Dada uma data como entrada em qualquer formato conveniente, produza um calendário com essa data como o centro exato de uma janela de cinco semanas. O cabeçalho do calendário deve incluir as abreviações de duas letras para os dias da semana (ou seja, Su Mo Tu We Th Fr Sa). Não são permitidas abreviações de três letras ou outros dias.

Por exemplo, dado April 2 2019como entrada, a saída deve ser

Sa Su Mo Tu We Th Fr
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31  1  2  3  4  5
 6  7  8  9 10 11 12
13 14 15 16 17 18 19

para que a data especificada seja o meio exato do calendário.

Dado February 19 2020, saída

Su Mo Tu We Th Fr Sa
 2  3  4  5  6  7  8
 9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
 1  2  3  4  5  6  7

Para September 14 1752, mostre o seguinte:

Mo Tu We Th Fr Sa Su
28 29 30 31  1  2  3
 4  5  6  7  8  9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  1

  • A entrada e a saída podem ser fornecidas por qualquer método conveniente .
  • A entrada é garantida como não vazia e válida (ou seja, você nunca receberá ""ou Feb 31etc.).
  • Suponha calendário gregoriano para todas as datas.
  • Os anos bissextos devem ser contabilizados.
  • As datas de entrada variam de Jan 1 1600a Dec 31 2500.
  • Você pode imprimi-lo em STDOUT ou retorná-lo como resultado de uma função.
  • Um programa completo ou uma função são aceitáveis.
  • Qualquer quantidade de espaço em branco estranho é aceitável, desde que os caracteres sejam alinhados adequadamente.
  • Os zeros à esquerda nos dias de um dígito são permitidos, assim como o alinhamento dos dias de um dígito a serem alinhados à esquerda.
  • As brechas padrão são proibidas.
  • Isso é portanto todas as regras usuais de golfe se aplicam e o código mais curto (em bytes) vence.
AdmBorkBork
fonte

Respostas:

12

R , 77 72 bytes

function(d,`~`=format)write(c(strtrim(d+-3:3~"%a",2),d+-17:17~"%e"),1,7)

Experimente online!

Saída corrigida para usar abreviações de 2 letras por dia.

-1 byte usando strtrimgraças a Aaron Hayman .

Os blocos datam os números com os 0s iniciais; recebe a entrada como a Date, que pode ser criada usando as.Date("YYYY/MM/DD").

Estranhamente curto para uma resposta R ...

Giuseppe
fonte
8

05AB1E , 175 174 172 171 160 bytes

¦WΘ1š-1šVтFY`2ô0Kθ4ÖUD2Qi\28X+ë<7%É31α}‹iY¬>0ëY1¾ǝDÅsD12‹i>1ë\1Dǝ¤>2}}ǝVY})DJIJk18+£35.£¬.•4ιõ÷‡o‹ƶ¸•2ôs`UÐ3‹12*+>13*5÷s3‹Xα©т%D4÷®т÷©4÷®·()DćsćsO7%._s€нT‰J«7ô»

Entrada no formato [day, month, year]. Saída com 0s iniciais para dias de um dígito e minúsculasmo por meio de su(1 byte pode ser adicionado, se titlecase é obrigatório).

Experimente online ou verifique todos os casos de teste .

Puta merda .. Esse pode ser o meu novo recorde de resposta mais longa do 05AB1E, e então incluo alguns desafios muito complexos de que fiz ...>.> EDIT: Hmm ok, quase ..; p

Nota importante: 05AB1E não possui componentes internos para objetos ou cálculos de data. O único construído em relação às datas que possui é o ano / mês / dia / hora / minutos / segundos / microssegundos de hoje.

Portanto, quase todo o código que você vê são cálculos manuais para calcular os dias anteriores e seguintes (incluindo transição ao longo dos anos e tendo em mente os anos bissextos) e calculando o dia da semana usando a congruência de Zeller .

Grandes partes do código são copiadas de desta minha resposta 05AB1E anterior , que também será relevante para a explicação abaixo.

Explicação:

Começamos indo para o primeiro dia do mês anterior:

¦          # Remove the first item (the days) from the (implicit) input
 W         # Get the minimum (without popping the list itself)
           # (since the year is guaranteed to be above 1599, this is the month)
  Θ        # Check if its exactly 1 (1 if 1, 0 if in the range [2,31])
   1š      # Prepend a 1 as list (so we now have either [1,1] or [1,0]
     -     # Subtract this from the month and year
      1š   # And prepend a 1 for the day
        V  # Pop and store this first day of the previous month in variable `Y`

Então eu uso essa data como data de início e calculo os próximos 100 dias:

тF    # Loop 100 times:
  Y`2ô0Kθ4ÖUD2Qi\28X+ë<731α}‹iY¬>0ëY1¾ǝDÅsD12i>1ë\1Dǝ¤>2}}ǝV
      #  Calculate the next day in line
      #  (see the linked challenge above for a detailed explanation of this)
   Y  #  And leave it on the stack
 })   # After the loop: wrap the entire stack into a list, which contains our 100 days

Então, com a data de entrada no meio, deixo apenas os 17 anteriores e 17 após essa data da lista:

DJ          # Duplicate the 100 dates, and join the day/month/year together to strings
  IJ        # Push the input, also joined together
    k       # Get the 0-based index of the input in this list
            # (the joins are necessary, because indexing doesn't work for 2D lists)
     18+    # Add 18 to this index (18 instead of 17, because the index is 0-based)
        £   # Only leave the first index+18 items from the 100 dates
     35.£   # Then only leave the last 35 items

Agora temos nossos 35 dias. O próximo passo é calcular o dia da semana e criar o cabeçalho da tabela de saída:

¬                # Get the first date of the list (without popping the list itself)
 .•4ιõ÷‡o‹ƶ¸•    # Push compressed string "sasumotuwethfr"
             2ô  # Split it into chunks of size 2
s                # Swap to get the first date again
 `UÐ312*+>13*5÷s3Xα©т%D4÷®т÷©4÷®·()DćsćsO7%
                 # Calculate the day of the week (sa=0; su=1; ...; fr=6)
                 # (see the linked challenge above for a detailed explanation of this)
  ._             # Rotate the list of strings that many times

Veja este 05AB1E ponta do meu (seção Como cordas compressa não fazem parte do dicionário? ) Para entender por que .•4ιõ÷‡o‹ƶ¸•é"sasumotuwethfr" .

Em seguida, criamos os dias para preencher a própria tabela com base em nossa lista de datas criada anteriormente. Que vamos mesclar junto com o cabeçalho. Após o qual podemos imprimir o resultado final:

s           # Swap to get the list of dates again
 €н         # Only leave the first item of each date (the days)
   T       # Take the divmod 10 of each
     J      # Join those divmod results together
            # (we now have leading 0s for single-digit days)
      «     # Merge this list together with the header list
       7ô   # Split it into chunks of size 7
         »  # Join each inner list by spaces, and then each string by newlines
            # (and output the result implicitly)
Kevin Cruijssen
fonte
2
Isso é uma enorme quantidade de trabalho!
Luis Mendo
2
Sim, Java é melhor que 05AB1E! : D Primeira vez, eu acho ;-)
Olivier Grégoire
@LuisMendo A maioria foi feita da última vez com o desafio vinculado, mas sim, deu muito trabalho ..;) A explicação foi adicionada.
Kevin Cruijssen 05/04
@ OlivierGrégoire Agora somos o mesmo número de adeus. ;)
Kevin Cruijssen
@ OlivierGrégoire E agora está mais baixo novamente, desculpe. ; p
Kevin Cruijssen 05/04
6

JavaScript (ES6),  141  126 bytes

Economizou 15 bytes emprestando da resposta.toUTCString().slice(0,2) de Neil

Recebe a entrada como um objeto Data.

f=(d,n=0)=>n<42?(D=new Date(d-864e5*(24-n)),n<7?D.toUTCString().slice(0,2):(i=D.getDate())>9?i:' '+i)+`
 `[++n%7&&1]+f(d,n):''

Experimente online!

Arnauld
fonte
Ah, eu poderia jurar que meu código falhou no terceiro caso de teste quando o escrevi originalmente ... bem, isso me salva 52 bytes ...
Neil
4

JavaScript (Node.js) , 205 152 145 bytes

f=
d=>`012345`.replace(g=/./g,r=>`0123456
`.replace(g,c=>`${new Date(d-864e5*(24-c-r*7))[+r?`getUTCDate`:`toUTCString`]()}`.slice(0,2).padStart(3)))
<input type=date oninput=o.textContent=f(this.valueAsDate)><pre id=o>

Experimente online! Recebe entrada como objeto Data JavaScript ou carimbo de data e hora. Edit: Salvo 1 byte graças a @EmbodimentofIgnorance, que me permitiu salvar mais 7 bytes adicionando uma nova linha à direita na saída. Salvei 52 bytes quando descobri que estava trabalhando com um comportamento que na verdade não era de buggy ...

Neil
fonte
padStart(2)-> padStart(3), remova o espaço na cadeia de junção de -1 byte
Modalidade de ignorância
3

Perl 6 , 87 bytes

{~rotate(<Th Fr Sa Su Mo Tu We>,.day-of-week),|comb 21,($_-17..$_+17)>>.day.fmt('%2d')}

Experimente online!

Pega um Dateobjeto, retorna uma lista de linhas.

Nwellnhof
fonte
2

Wolfram Language (Mathematica) , 123 bytes

(s=#;Grid@Join[{StringTake[ToString@DayName[s~d~#]&/@Range[-3,3],2]},Partition[Last@d[s,#]&/@Range[-17,17],7]])&
d=DatePlus

Experimente online!

Não sei por Gridque não funciona no TIO, mas esse código gera esse

insira a descrição da imagem aqui

@DavidC salvou 1 byte

J42161217
fonte
Talvez Gridnão funcione porque o TIO não pode centralizar os itens como na sua foto?
AdmBorkBork 5/04
@AdmBorkBork Existe uma maneira de carregar gráficos como este no TIO. Alguém me mostrou no ano passado, eu acho. Mas não me lembro como fazê-lo ... Então, se alguém souber, avise-nos!
J42161217 5/04
2

MATL , 34 33 31 bytes

YO-17:17+t7:)8XOO3Z(!1ew7XOU7e!

Experimente online!

Explicação

YO       % Implicit input. Convert to date number. This is a single number
         % that specifies the date
-17:17   % Push [-17 -16 ... 16 17]
+        % Add to date number, element-wise. This gives a row vector of 35
         % date numbers centered around the input date
t        % Duplicate
7:       % Push [1 2 ... 7]
)        % Index into the 35-element vector. This keeps the first 7 entries
8XO      % Convert to day-of-week in 3 letters. Gives a 3-col char matrix
O3Z(     % Write char 0 (equivalent to space for display purposes) into the
         % 3rd column
!1e      % Tranpose and linearize into a row. This produces a string such as
         % 'Tu We Th Fr Sa Su Mo ', to be used as column headings
w        % Swap. This brings to top the row vector of 35 date numbers
         % computed from the input
7XO      % Convert to day-of-month. Gives a 2-col char matrix
U        % Convert each row to number
7e!      % Reshape into 7-row matrix and transpose
         % Implicit display. This prints the string with the headings and
         % the matrix. The latter has a minimum-one-space separation between
         % columns, so it is aligned with the headings
Luis Mendo
fonte
2

Java (JDK) , 149 bytes

d->{d.add(5,-24);for(int i=0,w;i<42;d.add(5,1))System.out.printf("%c%2s",i%7<1?10:32,i++<7?"SaSuMoTuWeThFr".substring(w=d.get(7)%7*2,w+2):d.get(5));}

Experimente online!

Créditos

Olivier Grégoire
fonte
1
159 bytes
Kevin Cruijssen
1
@KevinCruijssen Wait ... what? Eu te parabenizo! Eu tentei fazer isso, mas não consegui encontrar uma maneira de fazê-lo, e você conseguiu! Muito bom :-)
Olivier Grégoire
1
Talvez você veja algo mais para combinar o ie de jalguma forma? Ou algo mais curto j++%7<1?10:32com alguma mágica bit a bit? Mas vou deixar isso para você. Estou voltando ao trabalho, lol. ;)
Kevin Cruijssen 05/04
1
Ah, claro .. Bom trabalho em equipe! ;) PS: Onde wrepresenta? Por que não hpara cabeçalho?
Kevin Cruijssen 5/04
1
@KevinCruijssen wpara "dia de w eek". Além disso, o ajuste de bits apenas pode levar a (i%7+6)/7*22+10que é muito mais longo.
Olivier Grégoire
2

PHP ,197 189 187 bytes

for($d=date_create($argn)->sub($i=new DateInterval(P17D)),$i->d=1;$x++<35;$h.=$x<8?substr($d->format(D),0,2).' ':'',$d->add($i))$o.=str_pad($d->format(j),3,' ',2);echo wordwrap($h.$o,20);

Experimente online!

A entrada é STDINcomo uma sequência de datas. Corra com php -nF.

$ echo April 2 2019|php -nF cal.php

Sa Su Mo Tu We Th Fr 
16 17 18 19 20 21 22 
23 24 25 26 27 28 29 
30 31  1  2  3  4  5 
 6  7  8  9 10 11 12 
13 14 15 16 17 18 19 

Verifique todos os casos de teste

Ou 174 bytes com dígitos únicos preenchidos com zero.

640KB
fonte
1

Excel VBA, 190 159 bytes

Obrigado @TaylorScott

Function z(i)
Dim d(5,6)
v=DateValue(i)-17
For x=1To 5
For y=0To 6
d(0,y)=Left(WeekdayName(Weekday(v+y)),2)
d(x,y)=day(v+y+(x-1)*7)
Next y,x
z=d()
End Function

Recebe entrada na forma de uma sequência de datas válida para o Excel VBA (por exemplo, 19 de fevereiro de 2020; 19/2/2020; 19 de fevereiro de 2019) e retorna uma matriz com o calendário especificado centralizado nela.

william porter
fonte
Você pode obter essa solução para 159 removendo o espaço em branco dessa solução.Function z(i) Dim d(5,6) v=DateValue(i)-17 For x=1To 5 For y=0To 6 d(0,y)=Left(WeekdayName(Weekday(v+y)),2) d(x,y)=Day(v+y+(x-1)*7) Next y,x z=d() End Function
Taylor Scott
@ TaylorScott Obrigado, estava usando apenas o editor interno que autopopula esses espaços.
william porter
0

Vermelho , 153 131 bytes

func[d][s: d - 24 loop 7[prin[""copy/part system/locale/days/(s/10) 2]s:
s + 1]loop 5[print""loop 7[prin pad/left s/4 3 s: s + 1]]]

Experimente online!

Galen Ivanov
fonte
0

T-SQL, 203 bytes

DECLARE @f date='2020-02-19'

,@ char(20)=0,@d char(105)=0SELECT
@=left(format(d,'D'),2)+' '+@,@d=right(d,2)+char(32-n%7/6*19)+@d
FROM(SELECT dateadd(d,number-17,@f)d,number n
FROM spt_values WHERE'P'=type)x ORDER BY-n
PRINT @+'
'+@d

A versão online é um pouco diferente, esta versão postada funciona no MS-SQL Studio Management. Ele salva 1 bytes em comparação com a versão online, mas não fornece o resultado correto online

Experimente online

t-clausen.dk
fonte
0

Python 2 , 115 bytes

from datetime import*
d=input()
for i in range(42):print(d+timedelta(i-24)).strftime('%'+'da'[i<7])[:2]+i%7/6*'\n',

Experimente online!

Não tenho certeza se isso é permitido ... recebe a entrada de STDIN no formulário date(year, month, day). Isso também pode ser representado como __import__('datetime').date(year, month, day). Estes são realmente __import__('datetime').dateobjetos.

Erik, o Outgolfer
fonte