Wie ist der heutige Tag (oder andere Daten)?

12

Aufgabe

Schreiben Sie ein Programm oder eine Funktion, die einen Wochentagsnamen eines Datums berechnet, das ein Benutzer eingibt.

Input-Output

Die Eingabe ist eine Zeichenfolge YYYYMMDD.

Beispiel für Eingabewerte:

20110617: 17. Juni 2011
19040229: 29. Februar 1904
06661225: 25. Dezember 666
00000101: 1. Januar 0
99991231: 31. Dezember 9999

Sie können davon ausgehen, dass alle Eingaben gültig sind. Beachten Sie, dass das Jahr Null gültig ist.

Die Ausgabe ist eine Ganzzahl zwischen 0und 6. Jede Ganzzahl steht für einen Wochentagsnamen. Sie können frei entscheiden, welche Ganzzahl einen Wochentagsnamen wie diesen darstellt

0: Montag
1: Dienstag
2: Mittwoch
...
6: Sonntag

(in der Reihenfolge) oder dieser

0: Montag
1: Mittwoch
2: Sonntag
...
6: Samstag

(nicht in der Reihenfolge).

Testfälle

Eingabe Wochentag Ausgabe ([0..6 -> Montag..Sonntag] wird in diesem Beispiel verwendet.)

20110617 Freitag 4
19500101 Sonntag 6
22220202 Samstag 5
19000228 Mittwoch 2
19000301 Donnerstag 3
19450815 Mittwoch 2
19040229 Montag 0
19040301 Dienstag 1
17760704 Donnerstag 3
20000228 Montag 0
20000229 Dienstag 1
20000301 Mittwoch 2
20121223 Sonntag 6
00000401 Samstag 5
66660606 Mittwoch 2
59161021 Samstag 5

Beschränkung

Sie dürfen nicht nutzen jede Art von Funktion / Klasse / ..., die Zeitstempel oder das Datum beziehen, wie DateKlasse in Java/ JavaScript/ ActionScriptoder getdateFunktion in PHP.

Sie sollten den Gregorianischen Kalender verwenden , der jetzt von vielen Menschen verwendet wird.

Natürlich gewinnt der kürzeste Code. Wenn zwei Codes die gleiche Länge haben, gewinnt der Code mit den höchsten Stimmen.

(Fällig: Wenn es mehr als 5 Codes gibt, die mehr als (oder gleiche) +1Stimmen haben.)

JiminP
quelle
Heute? Warum, Weihnachtstag!
Joey Adams
3
Optimistische Lösung in heftigen Schlag geschrieben (6 Zeichen): echo 4.
Wahrhaftigkeit
1
@trutheality Nein, das wollte ich nicht. Was ich wollte, ist ein Code, der den Wochentag eines eingegebenen Datums ausgibt / zurückgibt, nicht nur den Wochentag von heute.
JiminP
Oh ich weiss. Das ist es, was dieser macht.
Wahrhaftigkeit
Es ist richtig, mindestens 14% der Zeit!
Draco18s vertraut SE

Antworten:

2

Ruby, 95 92 Zeichen

Einfache, unkomplizierte Ruby-Implementierung mit 0: Montag, ...

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
Howard
quelle
4

PHP - 101 97 103 125 Zeichen

  • Sakamoto-Algorithmus
  • 0 = Sonntag

Code

<?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;

Hinweis

Aufgrund der dynamischen, schwachen Typisierung von PHP funktioniert der Sakamoto-Algorithmus leider nicht richtig, ohne jede Divisionsoperation explizit zu belegen.

Rintaun
quelle
Kannst du bitte nochmal testen? Seit einigen Jahren gibt es unterschiedliche Ergebnisse (z. B. liefert der Testfall 17760704 Dienstag statt Mittwoch).
Howard
@ Howard das ist sehr seltsam; für 17760704 bekomme ich mittwochs. Es treten jedoch andere Inkonsistenzen auf, die ich nicht berücksichtigen kann, z. B. die Rückkehr von 19040229 am Dienstag. Ich bin nicht sicher, was das verursachen könnte. Ich erhalte die gleichen Ergebnisse, wenn ich den Algorithmus wieder auf erweitere y+y/4-y/100+y/400.
Rintaun
Ich kann es mit 497 * y / 400 beobachten: y=4In diesem Fall wird 4 zurückgegeben, anstatt der korrekten 5 von y+y/4+y/100+y/400(wo nur die ersten beiden Terme ins Spiel kommen). Das ist es, was meine JavaScript-Antwort plagt. Ist es möglich, dass anstelle von Ints Doubles erstellt werden? (Mein PHP ist zu schwach, um es zu wissen.)
DocMax
@DocMax: Das Verlassen des Ausdrucks hat das gleiche Ergebnis (497y / 400 sollte äquivalent sein: y / 100 wird subtrahiert und y / 400 wird unabhängig davon erneut addiert). Ich vermute, dass PHP einfach alles nach dem Komma abhackt, anstatt es zu runden. Ich habe dies durch Abrunden vor dem Modulo getestet. Dies behebt zwei der Anomalien, aber 19040229 gibt immer noch das gleiche Ergebnis zurück. Irgendwelche anderen Ideen?
Rintaun
@Rintaun Ich glaube nicht, dass es die Rundung ist. Sie unterscheiden sich grundlegend. Nehmen Sie das obige Beispiel (y = 4): 497 * 4/400 = 1988/400 = 4, aber andererseits 4 + 4 / 4-4 / 100 + 4/400 = 4 + 1-0 + 0 = 5 . Die Terme / 100 und / 400 werden in Ihrer Berechnung zu stark gewichtet, sodass die 2000 nicht erreicht werden kann.
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);
}

Dies missbraucht, wie die Division zumindest auf meinem System (Linux x86) gegen Null rundet.

Die magische Konstante 86400dient zwei Zwecken:

  • Subtrahieren Sie das Jahr, um es negativ zu machen, ohne den Wochentag zu beeinflussen. Dies macht es so, dass die Divisionen auf- und abrunden.
  • Verschieben Sie die Tageszahl so, dass Montag 0 ist.

Es ist auch die Anzahl der Sekunden pro Tag.

Joey Adams
quelle
Verwenden Sie y+=m>2;statt m>2?y++:0;und rasieren Sie ein paar Bytes aus.
Klarer
2

Javascript, 126 123 Zeichen

Verwendung des Sakamoto-Algorithmus mit 0 = Sonntag:

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

Ich vermute, die Spaltungen können zusammenbrechen, aber im Moment sehe ich es nicht.

Bearbeiten: Die Unterteilungen wurden verbessert (keine Notwendigkeit, ~~wenn Sie nur können ~).

DocMax
quelle
2

Python 2 , 83 116 113 109 Bytes

Implementiert den Sakamoto-Algorithmus . Golfvorschläge sind willkommen. Probieren Sie es online!

Edit: Ich hätte das schon vor Ewigkeiten beheben sollen. -6 Bytes von Jonathan Allans Vorschlägen +2 Bytes, um den Code tatsächlich zu reparieren.

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
Sherlock9
quelle
Die Eingabe sollte eine einzelne Zeichenfolge sein.
msh210
int('032503514624'[m-1])Paraden 6
Jonathan Allan
0

Perl - 110 Bytes

Hier ist eine Lösung, die mit perl -p source.pl ODER perl -pe 'here-is-code' ausgeführt werden kann.

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

Kopieren Sie einfach die Testfälle nach stdin.

Dies scheint der einzige Code ohne Variablen, String-Konstanten und Divisionen zu sein.

Layosh
quelle
0

JavaScript (ES6), 73 Byte (nicht konkurrierend)

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

Versuch es

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>

Zottelig
quelle
Warum nicht konkurrieren?
programmer5000
@ programmer5000, überprüfe das Datum, an dem die Challenge gepostet wurde;)
Shaggy