Saída: mês do calendário (sem funções nativas de geração de calendário)

8

Ao receber mês e ano no formato AAAAMM, gere a saída do mês civil correspondente para esse ano.

Por exemplo, a entrada 201312deve gerar a seguinte saída:

Mo Tu We Th Fr Sa Su
                   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 31

O único truque é que NÃO há funções nativas de geração de calendário ... então clones do Linux, nenhuma função "cal" ... Muahahahahah!

PS: O calendário deve começar com segunda-feira como o dia mais à esquerda, para garantir que a saída seja como a função "cal", mas não seja como "cal", que tem domingo como o dia mais à esquerda. ..

O menor tamanho de código vence.

WallyWest
fonte
1
Você quer que pareça um calendário, pode alterar seu texto para dizer isso de forma mais clara. Além disso, quais são as condições vencedoras?
Justin
@Quincunx, você é como minha consciência, única digitais ...
Wally West
1
Só que eu não sou digitais ...
Justin
1
"O menor tamanho vence." tamanho de que? Se for o tamanho do código, altere a tag para code-golf
Justin
2
Presumo que você queira o calendário gregoriano, mas por que intervalo de anos?
Peter Taylor

Respostas:

6

Python 2.7 - 152

Infelizmente, falha em setembro de 1752 . Concedido, ele importa todas as funções do calendário, mas usa apenas 1, e isso apenas retorna o dia de início da semana e o número de dias.

from calendar import*
w,l=monthrange(*divmod(input(),100))
print" Mo Tu We Th Fr Sa Su\n"+"   "*w+''.join(["%3d"%s+"\n"*((s+w)%7<1)for s in range(1,l+1)])

Código relativamente padrão, mas este é o meu bit favorito:

"\n"*((s+w)%7<1)

Ela imprime a nova linha usando a multiplicação de cadeias, se o número do dia atual e do dia da semana inicial for domingo (por exemplo, 7), pois o booleano é convertido em um número inteiro.

Isso salva um personagem no mais intuitivo x%7==0, usando-o x%7<1.

Saída de teste:

> 198210
Mo Tu We Th Fr Sa Su
             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 31

fonte
deixe-me adivinhar: você acabou de traduzir minha abordagem para outro idioma e a versão ficou mais curta. Eu estou bem com isso, mas a divulgação seria legal.
John Dvorak
@JanDvorak Oh não. De modo nenhum. Eu não conseguia entender o seu. Para ser sincero, dadas as importações detalhadas de que eu precisava, fiquei chocado que ele chegasse perto de bater o seu. Apenas por curiosidade, o que está 52.timesfazendo? Não é multiplicação?
1
É uma construção em loop. n.times{...}é idêntico a (0...n).each{...}ou 0.upto(n-1){...}. A multiplicação seria52 * ...
John Dvorak
@JanDvorak Eu brinquei com Python há alguns anos em um trabalho em que estava trabalhando ... Achei a sintaxe de indentação um pouco dolorosa ... Então, acostumada a colchetes, acho ... AMO o "\ n" * ((s + w)% 7 <1) truque ... Eu nunca verificado para ver se isso iria funcionar em JavaScript ...;)
Wally West
A referência do Wiki que você mencionou foi interessante ... "Ele reformou o calendário da Inglaterra e dos Domínios Britânicos para que um novo ano começasse em 1º de janeiro em vez de 25 de março (Lady Day) e funcionasse de acordo com o calendário gregoriano, usado na maioria dos países. da Europa Ocidental ". Estou surpreso que os ingleses estavam um pouco atrasados ​​...?
Wally West
8

Rubi, 170 168 caracteres

g=gets.to_i
require'date'
d=Date.new g/100,g%100
puts'Mo Tu We Th Fr Sa Su'
l=['']*(d.jd%7)+[*1..(d>>1).jd-d.jd]
56.times{|i|$><<"#{l[i].to_s.rjust 2} #{?\n if i%7>5}"}

Correção de bug: não era necessário que a biblioteca necessária (+16) usasse a data juliana módulo 7 em vez do dia da semana atual diretamente (-3)
usasse / 100 e% 100 para analisar a data em vez da regex (-13). Retirado da resposta de LegoStormtroopr.
removeu os parênteses ao redor do argumento rjuste Date.new(-2)

John Dvorak
fonte
Legal. Não testado exaustivamente, mas parece que você pode mudar "#{l[i].to_s.rjust 2} #{?\n if i%7>5}"com "%2s %s"%[l[i],i%7>5?$/:""].
manatwork
5

Mathematica 203

g@d_:=Module[{w={"Mo","Tu","We","Th","Fr","Sa","Su"},c},
c@n_:=" "~ Table ~{n};
Grid@Partition[Join[w,c[Position[w,StringTake[ToString@DayName@d,2]][[1,1]]-1],
Range@DayCount[d,d~DatePlus~{1,"Month"}],c@6],7]]

Teste

g[{2013, 12}]
g[{2014, 1}]
g[{2014, 2}]

calendários

DavidC
fonte
Grande uso do Mathematica!
Wally West
2

SmileBASIC, 204 bytes

INPUT Y$Y$[3]=Y$[3]+"/
DTREAD Y$+"/01"OUT Y,M,,W
W=W-1+!W*7?"Mo Tu We Th Fr Sa Su
FOR I=1TO 30+(1AND M-(M>7))-(M==2)*2+(Y MOD 4<1&&(Y MOD 100||Y MOD 400<1))LOCATE W*3,?STR$(I,2);
W=W+1
IF W>6 THEN W=0?
NEXT

Uau, esse detector do ano bissexto é MUITO longo ...

12Me21
fonte
1

JavaScript (239)

h=prompt();y=h.slice(i=0,4);m=h[4]+h[5]-1;d=new Date(y,m);a='MoTuWeThFrSaSu'.match(/../g);for(p=0;p<(d.getDay()||7)-1;p++)a.push('  ');while(d.setDate(++i)&&d.getMonth()==m)a.push(9<i?i:' '+i);while(c=a.splice(0,7).join(' '))console.log(c)

Resultado:

(for 198210)                (for 201312)

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

PHP, 153 147 bytes

Mo Di We Th Fr Sa Su
<?=str_pad("",3*$w=date(w,$t=strtotime(chunk_split($argv[1],4,"-")."7")));while($d++<date(t,$t))printf("%2d "."
"[++$w%7],$d);

demolir

echo"Mo Di We Th Fr Sa Su\n";   // header
echo str_pad("",3*                      // 4. print leading spaces
    $w=date(w,                          // 3. get weekday
    $t=strtotime(                       // 2. convert to unix timestamp
        chunk_split($argv[1],4,"-")."7" // 1. import, split to year-month-, append day 7
)));
while($d++<date(t,$t))                  // 5. loop $d through days of month:
    printf("%2d "."\n"[++$w%7],$d);         // print date, plus a linebreak for sundays
Titus
fonte
0

C (gcc) , 242 bytes

Não é a solução mais elegante, eu suspeito.

Entrada na forma de um número inteiro com os quatro dígitos altos formando o ano e os dois dígitos baixos o mês.

X=100,W;f(d){int m=d%X,y=d/X,i=0,M=" >8><><>><><>"[m]/2+(m==2&(!(y%4)&&(y%X|!(y%400))));for(m+=m<3?y--,10:-2,W=(((1+(26*m-2)/10-2*y/X+5*(y%X)/4+y/X/4)%7)+6)%7,printf("Mo Tu We Th Fr Sa Su\n%*s",3*W,"");i<M;)printf("%2d%c",++i,W++%7^6?32:10);}

Experimente online!

gastropner
fonte
Sugerir em (13*m+4)/5+y%X*5/4-7*y/X/4vez de1+(26*m-2)/10-2*y/X+5*(y%X)/4+y/X/4
ceilingcat 15/07/19