128 anni? Ipotetica riforma dell'anno bisestile


23

L'anno solare è di 365 giorni, 5 ore, 48 minuti, 45 secondi e 138 millisecondi, secondo questo video . Con l'attuale calendario gregoriano, le regole per gli anni bisestili sono le seguenti:

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

Sfortunatamente, questo metodo è disattivato di un giorno ogni 3216 anni.

Un possibile metodo per riformare il calendario è la seguente regola:

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

Ciò ha il vantaggio di non richiederci di cambiare nuovamente i nostri calendari per altri 625.000 anni, dare o avere.

Supponiamo che il mondo intero decida che, a partire da ora, utilizziamo questo sistema ogni quattro anni è un anno bisestile, tranne ogni 128 anni, cambiando i nostri calendari come segue:

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

In che modo ciò influirebbe sugli algoritmi del giorno della settimana?

La sfida

  • Data una data dall'anno 2000 all'anno 100000, trova il giorno della settimana in questo nuovo calendario.
  • È consentito qualsiasi formato di input e output purché si specifichino chiaramente quali formati si stanno utilizzando.
  • Questo è il golf del codice, quindi cerca di rendere le tue soluzioni il più golfose possibile!

Casi test

"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

Suggerimenti e feedback sulla sfida sono i benvenuti. Buona fortuna e buon golf!


Per il caso di test n. 4, intendi 1 indicizzato, giusto? Altrimenti ci dovrebbero essere 8 giorni in quella settimana.
Sebastian,

Inoltre, dici "buon golf", quindi questa è una sfida # codice-golf? In tal caso, inserisci i criteri vincenti (ad es. Numero più basso di byte / caratteri) e aggiungilo come tag.
Sebastian,

@Sebastian Hai ragione su entrambi i punti. Ho già modificato la sfida. Grazie per il tuo feedback
Sherlock9

1
Durante la lettura del titolo, ho pensato immensamente al video di Matt Parker. Bello vederlo collegato anche nel thread: D
PattuX

1
Basta prendere le librerie standard del giorno della settimana e modificare le costanti globali di conseguenza, giusto? ;)
Wildcard

Risposte:


8

C (gcc) , 60 byte

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

Provalo online!

Semplice modifica del metodo di Sakamoto . Prende l'input come argomenti interi nell'ordine month, day, yeare restituisce il numero del giorno (indicizzato 0 domenica).


Cosa fa la "-bed=pen+mad."parte?
ericw31415,

@ ericw31415 Rappresenta la lunghezza di ogni mese in giorni, e semplicemente per il gusto dell'apparenza viene spostato di multipli di 7 invece di essere caratteri ordinali (31, 28 ...).
Notjagan,

Bene, ho dimenticato che charrappresenta ancora un numero, quindi puoi farlo mod 7direttamente.
ericw31415,

6

Wolfram Language (Mathematica) , 57 55 53 byte

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

Provalo online!

Accetta tre input: l'anno, il mese e il giorno, in quell'ordine. Ad esempio, se salvi la funzione precedente come fun, fun[2048,2,28]ti dice il giorno della settimana del 28 febbraio 2048.

Come funziona

La formula m=#~Mod~128;6+Mod[(9#-m)/8-6Clip@m,28] converte l'anno in un anno equivalente (un anno con esattamente gli stessi giorni della settimana) tra il 6 d.C. e il 33 d.C. Per fare ciò, sottraggiamo un offset e poi prendiamo l'anno mod 28; ma la compensazione cambia ogni 128 anni, e per anni divisibili per 128, dobbiamo fare un ulteriore aggiustamento perché l'anno equivalente non dovrebbe essere un anno bisestile.

Ad ogni modo, una volta fatto, cerchiamo il mese e il giorno in quell'anno equivalente usando il built-in DayName.



3

JavaScript, 65 59 byte

(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)

Usa il metodo di Sakamoto. dà0=Sunday, 1=Monday, 2=Tuesday...

-2 byte grazie a Misha Lavrov
-4 byte grazie ad Arnauld


1
Penso che ~~ypossa essere cambiato in y. Non otterrai un anno frazionario nell'input, giusto? Ma ammetto di non essere fluente in JavaScript.
Misha Lavrov,

2
Che ne dici +y+(y>>2)-(y>>7)?
Arnauld,

@MishaLavrov Sì, è vero. Per qualche motivo ho deciso che avrei dovuto pavimentare tutto.
ericw31415,

2

In realtà , 37 byte

Questa è una porta della modifica di Notjagan dell'algoritmo di Sakamoto , ma con alcuni trucchi basati sullo stack come descritto di seguito. Il formato di input è day, year, month. Il formato di output è 0-indexed with Sunday as 0. Suggerimenti di golf benvenuti! Provalo online!

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

Spiegazione

                     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

2

Gelatina , 32 31 30 28 byte

Un'altra porta della modifica di Notjagan dell'algoritmo di Sakamoto ma con un numero di base 250 al posto di 032503514624(non è necessario il supplemento 0perché Jelly è 1-indicizzata). Il formato di input è month, year, day. Il formato di output è 0-based with Sunday as 0. I suggerimenti sul golf sono molto apprezzati in quanto il modo in cui i collegamenti sono stati difficili da organizzare e può essere ancora golfabile. Provalo online!

Modifica: -1 byte dall'uso del bit shift invece della divisione intera. -1 byte dal riordino dell'inizio e del formato di input. -2 byte grazie a Erik the Outgolfer e caird coinheringaahing.

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

Spiegazione

         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.

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.