128 Jahre? Hypothetische Schaltjahrreform

23

Das Sonnenjahr beträgt laut diesem Video 365 Tage, 5 Stunden, 48 Minuten, 45 Sekunden und 138 Millisekunden . Mit dem aktuellen Gregorianischen Kalender gelten folgende Regeln für Schaltjahre:

if      year is divisible by 400, LEAP YEAR
else if year is divisible by 100, COMMON YEAR
else if year is divisible by 4,   LEAP YEAR
else,                             COMMON YEAR

Leider ist diese Methode alle 3216 Jahre um einen Tag verschoben.

Eine mögliche Methode zur Reformierung des Kalenders ist die folgende Regel:

if      year is divisible by 128, COMMON YEAR
else if year is divisible by 4,   LEAP YEAR
else,                             COMMON YEAR

Dies hat den Vorteil, dass wir unsere Kalender für weitere 625.000 Jahre nicht erneut ändern müssen.

Angenommen, die ganze Welt beschließt, dass dieses System ab sofort jedes vierte Jahr ein Schaltjahr ist, mit Ausnahme jedes 128. Jahres, und unsere Kalender wie folgt ändert:

YEAR    GREGORIAN    128-YEAR
2044    LEAP         LEAP
2048    LEAP         COMMON
2052    LEAP         LEAP
 ...
2096    LEAP         LEAP
2100    COMMON       LEAP
2104    LEAP         LEAP
 ...
2296    LEAP         LEAP
2300    COMMON       LEAP
2304    LEAP         COMMON
2308    LEAP         LEAP

Wie würde sich dies auf unsere Algorithmen für den Wochentag auswirken?

Die Herausforderung

  • Wenn Sie ein Datum zwischen 2000 und 100000 eingeben, suchen Sie den Wochentag unter diesem neuen Kalender.
  • Jedes Eingabe- und Ausgabeformat ist zulässig, solange Sie klar angeben, welche Formate Sie verwenden.
  • Dies ist Codegolf, also versuchen Sie, Ihre Lösungen so golfig wie möglich zu gestalten!

Testfälle

"28 February 2048" -> "Friday"
"March 1, 2048"    -> "Sat"
(2100, 2, 29)      -> 0           # 0-indexed with Sunday as 0
"2100-02-29"       -> 7           # 1-indexed with Sunday as 7
"28 Feb. 2176"     -> "Wednesday"
"1-Mar-2176"       -> "Th"
"28/02/100000"     -> "F"         # DD/MM/YYYYYY
"Feb. 29, 100000"  -> 6           # 1-indexed with Sunday as 7
"03/01/100000"     -> 1          # MM/DD/YYYYYY and 1-indexed with Sunday as 1

Anregungen und Feedback zur Herausforderung sind willkommen. Viel Glück und gutes Golfen!

Sherlock9
quelle
Für Testfall 4 meinen Sie 1-indiziert, richtig? Ansonsten müsste es in dieser Woche 8 Tage geben.
Sebastian
Sie sagen auch "Gutes Golfen", ist dies also eine # Code-Golf-Herausforderung? Wenn ja, geben Sie die Gewinnkriterien ein (z. B. die niedrigste Anzahl an Bytes / Zeichen) und fügen Sie diese als Tag hinzu.
Sebastian
@ Sebastian Sie sind in beiden Punkten richtig. Ich habe die Herausforderung bereits bearbeitet. Vielen Dank für Ihr Feedback
Sherlock9
1
Wenn ich den Titel lese, sehe ich sofort Matt Parkers Video. Schön, dass es auch im Thread verlinkt ist: D
PattuX 30.11.17
1
Nehmen Sie einfach die Standardbibliotheken für Wochentage und ändern Sie die globalen Konstanten entsprechend, oder? ;)
Wildcard

Antworten:

8

C (gcc) , 60 Bytes

f(m,d,y){y-=m<3;return(y+y/4-y/128+"-bed=pen+mad."[m]+d)%7;}

Probieren Sie es online!

Einfache Modifikation der Sakamoto-Methode . Nimmt Eingaben als Ganzzahlargumente in die Reihenfolge month, day, yearund gibt die Nummer des Tages aus (am Sonntag mit 0 indiziert).

notjagan
quelle
Was macht das "-bed=pen+mad."Teil?
ericw31415
@ ericw31415 Er gibt die Länge jedes Monats in Tagen an und wird lediglich der Darstellung halber um ein Vielfaches von 7 verschoben, anstatt Zeichen bei Ordnungszahlen zu sein (31, 28 ...).
Notjagan
Richtig, ich habe vergessen, dass das charimmer noch eine Zahl darstellt, also kannst du das mod 7direkt machen.
ericw31415
6

Wolfram Language (Mathematica) , 57 55 53 Bytes

DayName@{m=#~Mod~128;6+Mod[(9#-m)/8-6Clip@m,28],##2}&

Probieren Sie es online!

Übernimmt drei Eingaben: das Jahr, den Monat und den Tag in dieser Reihenfolge. Wenn Sie die obige Funktion beispielsweise als speichern fun, fun[2048,2,28]wird der Wochentag des 28. Februar 2048 angezeigt.

Wie es funktioniert

Die Formel m=#~Mod~128;6+Mod[(9#-m)/8-6Clip@m,28]wandelt das Jahr in ein äquivalentes Jahr (ein Jahr mit genau denselben Wochentagen) zwischen 6 und 33 n. Chr. Um. Dazu subtrahieren wir einen Offset und nehmen dann das Jahr Mod 28; Der Offset ändert sich jedoch alle 128 Jahre, und für Jahre, die durch 128 teilbar sind, müssen wir eine weitere Anpassung vornehmen, da das entsprechende Jahr kein Schaltjahr sein sollte.

Sobald dies erledigt ist, suchen wir den Monat und den Tag in dem entsprechenden Jahr mithilfe der integrierten Funktion DayName.

Mischa Lawrow
quelle
3

Python 2 , 67 Bytes

def f(m,d,y):y-=m<3;return(y+y/4-y/128+int("0032503514624"[m])+d)%7

Probieren Sie es online!

int("..."[m])kann durch ersetzt werden ord("-bed=pen+mad."[m]).

Mr. Xcoder
quelle
3

JavaScript, 65 59 Bytes

(d,m,y)=>(y-=m<3,(+"0032503514624"[m]+y+(y>>2)-(y>>7)+d)%7)

(d,m,y)=>(y-=m<3,(+"0032503514624"[m]+~~y+~~(y/4)-~~(y/128)+d)%7)

Verwendet die Methode von Sakamoto. Gibt0=Sunday, 1=Monday, 2=Tuesday...

-2 Bytes dank Mischa Lawrow
-4 Bytes dank Arnauld

ericw31415
quelle
1
Ich glaube ~~y kann nur geändert werden y. Sie werden kein Bruchjahr in der Eingabe bekommen, richtig? Aber ich gebe zu, dass ich JavaScript nicht fließend beherrsche.
Mischa Lawrow
2
Wie wäre es +y+(y>>2)-(y>>7)?
Arnauld
@ Mischa Lawrow Ja, das ist wahr. Aus irgendeinem Grund habe ich beschlossen, dass ich alles auslegen sollte.
ericw31415
2

Eigentlich 37 Bytes

Dies ist ein Hafen von Notjagans Modifikation des Sakamoto-Algorithmus , jedoch mit ein paar stapelbasierten Tricks, wie unten beschrieben. Eingabeformat ist day, year, month. Ausgabeformat ist 0-indexed with Sunday as 0. Golfvorschläge willkommen! Probieren Sie es online!

;"0032503514624"Ei)3>±+;¼L;¼¼½L±kΣ7@%

Erläuterung

                     Implicit input: day, year, month (month is at TOS)
;"0032503514624"Ei)  Get the month code, convert to float, rotate to bottom of the stack
3>±+                 If 3>month, add -1 to year
;¼L                  Push floor(year/4) to stack
;¼¼½L±               Push floor(year/4) and append -floor(year/128) to stack.
kΣ                   Wrap the stack (y/128, y/4, y, month_code, d) in a list and sum
7@%                  Get the sum modulo 7
                     Implicit return
Sherlock9
quelle
2

Jelly , 32 31 30 28 Bytes

Eine weitere Portierung von Notjagans Modifikation des Sakamoto-Algorithmus, aber mit einer Basis-250-Zahl anstelle von 032503514624(brauche das Extra nicht, 0weil Jelly 1-indiziert ist). Eingabeformat istmonth, year, day . Ausgabeformat ist 0-based with Sunday as 0. Golfvorschläge sind sehr willkommen, da die Verbindungen schwierig zu arrangieren waren und möglicherweise noch golffähig sind. Probieren Sie es online!

Bearbeiten: -1 Byte von der Verwendung der Bitverschiebung anstelle der Ganzzahldivision. -1 Byte von der Neuordnung des Anfangs und des Eingabeformats. -2 Bytes dank Erik the Outgolfer und caird coinheringaahing.

3>_@µæ»7,2I+µ“Ṿ⁵Ḥ9{’D³ị+⁵+%7

Erläuterung

         Three arguments: month, year, day
3>_@     Subtract (month<3) from year. Call it y.
µ        Start a new monadic chain.
æ»7,2    Bit shift y by both 7 and 2 (equivalent to integer division by 128 and by 4).
I+       y + y/4 - y/128
µ        Start a new monadic chain.
“Ṿ⁵Ḥ9{’  The number 732573514624 in base 250.
D        The list [7, 3, 2, 5, 7, 3, 5, 1, 4, 6, 2, 4].
³ị       Get the month code from the list (1-based indexing).
+⁵+      Add y, our month code, and day together.
%7       Modulus 7.
Sherlock9
quelle
29 Bytes
Caird Coinheringaahing