Che giorno è oggi (o altre date)?


12

Compito

Scrivi un programma o una funzione che calcola il nome di un giorno della settimana di una data immessa da un utente.

Input Output

Ingresso è una stringa, YYYYMMDD.

Esempio di valori di input:

20110617: 17 giugno 2011
19040229: 29 febbraio 1904
06661225: 25 dicembre 666
00000101: 1 gennaio 0
99991231: 31 dicembre 9999

Si può presumere che tutti gli input siano validi. Si noti che l' anno zero è valido.

L'output è un numero intero compreso tra 0e 6. Ogni numero intero rappresenta un nome del giorno della settimana. Puoi decidere liberamente quale numero intero rappresenta un nome del giorno della settimana, come questo

0: lunedì
1: martedì
2: mercoledì
...
6: domenica

(in ordine) o questo

0: lunedì
1: mercoledì
2: domenica
...
6: sabato

(non in ordine).

Casi test

Input Output del giorno della settimana ([0..6 -> Monday..Sunday] viene utilizzato in questo esempio.)

20110617 venerdì 4
19500101 domenica 6
22220202 sabato 5
19000228 mercoledì 2
19000301 giovedì 3
19450815 Mercoledì 2
19040229 lunedì 0
19040301 martedì 1
17760704 giovedì 3
20000228 lunedì 0
20000229 martedì 1
20000301 mercoledì 2
20121223 domenica 6
00000401 sabato 5
66660606 Mercoledì 2
59161021 sabato 5

Restrizione

Non è necessario utilizzare alcun tipo di funzione / classe / ... correlati a data / ora, ad esempio Dateclasse in Java/ JavaScript/ ActionScripto getdatefunzione in PHP.

Dovresti usare il calendario gregoriano , che ora è usato da molte persone.

Naturalmente vince il codice più corto. Se due codici hanno la stessa lunghezza, vince il codice con il punteggio più alto.

(Scaduto: quando ci sono più di 5 codici con più di (o uguali) +1voti.)


Oggi? Perché, il giorno di Natale!
Joey Adams,

3
Soluzione Ottimista scritto in Bash (6 caratteri): echo 4.
verità,

1
@trutheality No, non intendevo questo ... Quello che volevo è un codice che stampa / restituisce il giorno della settimana di una data digitata da qualcuno, non solo il giorno della settimana di oggi.
JiminP,

Oh lo so. Questo è quello che fa questo.
verità,

È giusto almeno il 14% delle volte!
Draco18s non si fida più di SE

Risposte:


2

Rubino, 95 92 caratteri

Semplice implementazione rubino semplice con 0: lunedì, ...

p ((y=(d=gets.to_i)/(k=100)/k-((m=d/k%k)<3?1:0))+y/4-y/k+y/400+"squsptrotqro"[-m].ord+d%k)%7

4

PHP - 101 97 103 125 caratteri

  • Algoritmo di Sakamoto
  • 0 = domenica

Codice

<?php fscanf(STDIN,"%4d%2d%2d",$y,$m,$d);@$a=a032503514624;$y-=$m<3;$z=$y+1;echo($y+$y/4%$z-$y/100%$z+$y/400%$z+$a[$m]+$d)%7;

Nota

Sfortunatamente, a causa della digitazione dinamica e debole di PHP, l'algoritmo Sakamoto non funziona correttamente senza esplicitamente pavimentare ogni divisione.


Puoi ripetere il test? Per alcuni anni mi dà risultati diversi (es. Testcase 17760704 produce martedì invece di mercoledì).
Howard,

@Howard è molto strano; per 17760704, arrivo mercoledì. Ricevo altre incongruenze, che non posso spiegare, ad esempio 19040229 restituisce martedì. Non sono sicuro di cosa potrebbe causare questo. Ottengo gli stessi risultati quando espando nuovamente l'algoritmo y+y/4-y/100+y/400.
rintaun,

Posso vederlo accadere con 497 * y / 400: y=4in questo caso restituisce 4, anziché i 5 corretti da y+y/4+y/100+y/400(in cui entrano in gioco solo i primi due termini). Questo è ciò che affligge la mia risposta JavaScript. È possibile che vengano creati doppi invece di ints? (Il mio PHP è troppo debole per saperlo.)
DocMax,

@DocMax: lasciare l'espressione espansa ha lo stesso risultato (497y / 400 dovrebbe essere equivalente: y / 100 viene sottratto e y / 400 aggiunto di nuovo a prescindere). Immagino che PHP stia semplicemente tagliando tutto dopo il decimale invece di arrotondarlo. Ho provato questo arrotondando prima del modulo. Ciò risolve due delle anomalie, ma 19040229 restituisce comunque lo stesso risultato. Altre idee?
rintaun,

@rintaun non penso che sia l'arrotondamento. Sono fondamentalmente diversi. Prendi l'esempio dall'alto (y = 4): 497 * 4/400 = 1988/400 = 4 ma d'altra parte 4 + 4 / 4-4 / 100 + 4/400 = 4 + 1-0 + 0 = 5 . I termini / 100 e / 400 ottengono un peso eccessivo nel calcolo in modo da non poter raggiungere il 2000.
Howard,

2

C - 129

main(y,m,d,s)
{
    scanf("%04d%02d%02d",&y,&m,&d);
    y-=s=86400;
    d+=y+"-addgbegcfadf"[m];
    m>2?y++:0;
    putchar(48+(d+y/4-y/100+y/400+s+s)%7);
}

Questo abusa del modo in cui la divisione viene arrotondata a zero, almeno sul mio sistema (Linux x86).

La costante magica 86400, ha due scopi:

  • Sottrai dall'anno per renderlo negativo, senza influenzare il giorno della settimana. Questo lo rende in modo che le divisioni arrotondino per eccesso anziché per difetto.
  • Sposta il numero del giorno in modo che lunedì sia 0.

Capita anche di essere il numero di secondi in un giorno.


Utilizzare y+=m>2;invece di m>2?y++:0;e rasare alcuni byte.
Più chiaro il

2

Javascript, 126 123 caratteri

Utilizzando l'algoritmo di Sakamoto con 0 = domenica:

prompt().replace(/(....)(..)(..)/,function(_,y,m,d){y-=m<3;alert((+d+y-~(y/4)+~(y/100)-~(y/400)+ +".621462403513"[+m])%7)})

Sospetto che le divisioni possano essere crollate, ma in questo momento non lo vedo.

Modifica: migliorate le divisioni (non è necessario ~~quando puoi semplicemente ~).


2

Python 2 , 83 116 113 109 byte

Implementa l'algoritmo di Sakamoto . Suggerimenti di golf benvenuti. Provalo online!

Modifica: avrei dovuto risolvere questo problema secoli fa. -6 byte dai suggerimenti di Jonathan Allan +2 byte per correggere effettivamente il codice.

def w(s):m=int(s[4:6]);y,d=int(s[:4])-(m<3),int(s[6:]);return(y+y/4-y/100+y/400+int('032503514624'[m-1])+d)%7

L'input dovrebbe essere una singola stringa.
msh210,

int('032503514624'[m-1])salva 6
Jonathan Allan il

0

Perl - 110 byte

Ecco una soluzione da eseguire con perl -p source.pl OPPURE perl -pe 'here-is-code'.

s/((..)(..))(..)(..)/(1+3*$1+$2-2*($1%4+$2%4)-(2<$4?$4+(1&$4&&4-(8&$4)):(2^$4)+(!($3%4)-!-$3+!($2%4)))+$5)%7/e

Copia e incolla semplicemente i casi di test su stdin.

Questo sembra essere l'unico codice senza variabili, costanti di stringa e divisioni.


0

JavaScript (ES6), 73 byte (non concorrenti)

d=>(w=new Date(d[s="slice"](0,4),d[s](4,6)-1,d[s](-2)).getDay())-(w?1:-6)

Provalo

f=
d=>(w=new Date(d[s="slice"](0,4),d[s](4,6)-1,d[s](-2)).getDay())-(w?1:-6)
o.innerText=f(i.value="59161021")
oninput=_=>i.value.length==8&&(o.innerText=f(i.value))
<input id=i type=number><pre id=o>


Perché non competere?
programmatore

@ programmer5000, controlla la data di pubblicazione della sfida;)
Shaggy,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.