Calcola la data di Pasqua


13

La tua funzione o programma dovrebbe richiedere un anno come input e restituire (o stampare) la data (nel calendario gregoriano) di quegli anni Pasqua (non la Pasqua ortodossa orientale). La data restituita deve essere formattata secondo ISO 8601, ma con supporto per anni superiori a 9999 (come 312013-04-05 o 20010130 ) e deve funzionare solo con anni superiori o uguali a 1583 (l'anno del adozione del calendario gregoriano), e anni inferiori o uguali a 5701583 (com'è allora che la sequenza delle date di Pasqua inizia a ripetersi).

Esempi:

e(5701583) = 5701583-04-10
e(2013)    = 2013-03-31
e(1583)    = 1583-04-10
e(3029)    = 30290322
e(1789)    = 17890412
e(1725)    = 17250401

L'uso di funzioni integrate per la restituzione della data di pasqua è noioso e quindi vietato. Vince la risposta più breve (in caratteri).

risorse:


Ti rendi conto che alcune lingue hanno una funzione integrata per farlo?
Peter Taylor,

Ad esempio? L'unica di cui sono a conoscenza è PHP, ma le funzioni easter_date e easter_days sono piuttosto limitate, easter_date funziona solo per anni dopo il 1970 e easter_days non restituisce il numero corretto di giorni per anni prima del 1753. Ma modificherò la domanda per impedire l'uso di tali funzioni.
Fors,


1
Quindi questo è gregoriano e NON giuliano? Inoltre, non sono cattolico, che cos'è la "Tradizione cattolica?"
jdstankosky,

Risposte:


3

GolfScript (85 caratteri)

~:^100/.)3*4/.@8*13+25/-^19%.19*15+@+30%.@11/+29/23--.@-^.4/++7%97--^0@.31/100*\31%)+

Esempio di utilizzo:

$ golfscript.rb codegolf11132.gs <<<2013
20130331

Si noti che questo utilizza un algoritmo diverso rispetto alla maggior parte delle risposte correnti. Per essere precisi, ho adattato l'algoritmo attribuito a Lichtenberg nella risorsa collegata da Sean Cheshire in un commento sulla domanda.

L'algoritmo originale, assumendo tipi sensibili (cioè non i numeri di JavaScript) e con un adattamento per dare mese * 31 + giorno (usando un offset del giorno di 0) è

K = Y/100
M = 15 + (3*K+3)/4 - (8*K+13)/25
S = 2 - (3*K+3)/4
A = Y%19
D = (19*A+M) % 30
R = (D + A/11)/29
OG = 21 + D - R
SZ = 7 - (Y + Y/4 + S) % 7
OE = 7 - (OG-SZ) % 7
return OG + OE + 92

Ho estratto una sottoespressione comune e ho fatto alcune altre ottimizzazioni per ridurla

K = y/100
k = (3*K+3)/4
A = y%19
D = (19*A+15+k-(8*K+13)/25)%30
G = 23+D-(D+A/11)/29
return 97+G-(G+y+y/4-k)%7

Questo approccio ha operazioni aritmetiche leggermente più numerose dell'altro (l'algoritmo 20-op di Al Petrofsky), ma ha costanti più piccole; GolfScript non deve preoccuparsi delle parentesi extra perché è basato sullo stack e poiché ogni valore intermedio nel mio layout ottimizzato viene utilizzato esattamente due volte, si adatta perfettamente alla limitazione di GolfScript di un facile accesso ai primi tre elementi dello stack.


Ha un piccolo problema, quando la data di Pasqua è compresa tra il 1 aprile e il 10 aprile, restituisce date come 1725041, quando dovrebbe tornare 17250401. Ma è stato votato per il diverso approccio!
Fors l'

@Fors, oops. Ora risolto.
Peter Taylor,

5

Python 2 - 125 120 119 caratteri

Questa è la risposta di Fors spudoratamente portata su Python.

y=input()
a=y/100*1483-y/400*2225+2613
b=(y%19*3510+a/25*319)/330%29
b=148-b-(y*5/4+a-b)%7
print(y*100+b/31)*100+b%31+1

Modifica : modificata l'ultima riga da print"%d-0%d-%02d"%(y,b/31,b%31+1)per salvare 5 caratteri. Mi sarebbe piaciuto rappresentare 10000come 1e4, ma questo avrebbe prodotto un virgola mobile che richiedeva una chiamata int.

Edit2 : Grazie a Peter Taylor per aver mostrato come liberarsene 10000e salvare 1 personaggio.


1
Se si divide 10000fino a 100*100che si può mettere l'ultima riga in forma di Horner come (y*100+b/31)*100+b%31+1. La parentesi iniziale consente di rimuovere lo spazio dopo print, ed è possibile estrarre le tre istanze di 100una variabile per un risparmio complessivo di 1 carattere.
Peter Taylor,

@PeterTaylor: eccellente suggerimento. Aggiornato la mia risposta.
Steven Rumbalski,

Puoi renderlo una funzione e(y)e salvare alcuni byte
sagiksp,

4

PHP 154

150 caratteri se passo a AAAAMMGG anziché AAAA-MM-GG.

<?$y=$argv[1];$a=$y/100|0;$b=$a>>2;$c=($y%19*351-~($b+$a*29.32+13.54)*31.9)/33%29|0;$d=56-$c-~($a-$b+$c-24-$y/.8)%7;echo$d>31?"$y-04-".($d-31):"$y-03-$d";

Con interruzioni di riga:

<?
$y = $argv[1];
$a = $y / 100 |0;
$b = $a >> 2;
$c = ($y % 19 * 351 - ~($b + $a * 29.32 + 13.54) * 31.9) / 33 % 29 |0;
$d = 56 - $c - ~($a - $b + $c - 24 - $y / .8) % 7;
echo $d > 31 ? "$y-04-".($d - 31) : "$y-03-$d";

Utilizzo: php easter.php 1997
Uscita:1997-03-30

Utilizzo: php easter.php 2001
Uscita:2001-04-15


1
Grande algoritmo golf, codice golf non così grande. Mi sono preso la libertà di tagliare 18 byte:<?=$y=$argv[1],"-0",3+$m=($d=56-($c=($y%19*351-~(($a=$y/100|0)*29.32+($b=$a>>2)+13.54)*31.9)/33%29)-~($a-$b+$c-24-$y/.8)%7)>>5,31*$m-$d;
Tito

Non riesce a soddisfare il formato di output. Lo zero iniziale per il giorno non è presente dove necessario. Ad esempio per l'anno 1725 esce 1725-04-1invece di 1725-04-01.
Christoph,

4

dc: 106 caratteri

?[0n]smdndsy100/1483*ly400/2225*-2613+dsa25/319*ly19%3510*+330/29%sb148lb-5ly*4/la+lb-7%-d31/0nn31%1+d9>mp

Uso:

> dc -e "?[0n]smdndsy100/1483*ly400/2225*-2613+dsa25/319*ly19%3510*+330/29%sb148lb-5ly*4/la+lb-7%-d31/0nn31%1+d9>mp"
1725
17250401
>

Questo dovrebbe poter essere abbreviato usando 'd' e 'r' invece di tutti i carichi e le scorte.


3

C: 151 148 caratteri

y;a;b;main(){scanf("%d",&y);a=y/100*1483-y/400*2225+2613;b=(y%19*3510+a/25*319)/330%29;b=148-b-(y*5/4+a-b)%7;printf("%d-0%d-%02d\n",y,b/31,b%31+1);}

E lo stesso codice, ma meglio formattato:

#include <stdio.h>

int y, a, b;

int main() {
    scanf("%d", &y);

    a = y/100*1483 - y/400*2225 + 2613;
    b = (y%19*3510 + a/25*319)/330%29;
    b = 148 - b - (y*5/4 + a - b)%7;

    printf("%d-0%d-%02d\n", y, b/31, b%31 + 1);
}

Ci sono spaventosamente molti algoritmi per calcolare la data di Pasqua, ma solo alcuni sono adatti per giocare a golf.


3

Javascript 162 156 145

function e(y){alert(y+"0"+((d=56-(c=(y%19*351-~((b=(a=y/100|0)>>2)+a*29.32+13.54)*31.9)/33%29|0)-~(a-b+c-24-y/.8)%7)>(f=31)?4:3)+(d-f>0&d-f<10?0:"")+(d>f?d-f:d))}

Ispirato dalla soluzione PHP di @ jdstankosky ... Fornisce il risultato AAAAMMGG ...

Ora ristretto a:

alert((y=prompt())+0+((d=56-(c=(y%19*351-~((b=(a=y/100|0)>>2)+a*29.32+13.54)*31.9)/33%29|0)-~(a-b+c-24-y/.8)%7)>(f=31)?4:3)+(d-f>0&d-f<10?0:"")+(d>f?d-f:d))

Ora chiede input ... stringa letterale ridotta di "0" a 0 e lascia che la digitazione libera funzioni a mio vantaggio! :)

Ridotto ulteriormente per tener conto dell'ES6 ...

e=y=>y+"0"+((d=56-(c=(y%19*351-31.9*~((b=(a=y/100|0)>>2)+29.32*a+13.54))/33%29|0)-~(a-b+c-24-y/.8)%7)>(f=31)?4:3)+(d-f>0&d-f<10?0:"")+(d>f?d-f:d)


2

APL 132

Questo algoritmo calcola il numero di giorni in cui si trova la Pasqua rispetto all'inizio di marzo. La data viene restituita nel formato AAAAMMGG come consentito nella domanda:

E y                                                   
(a b)←⌊((3 8×⌊y÷100)+¯5 13)÷4 25                           
c←7|y+(⌊y÷4)-a-e←⌊d-((19×d←30|(227-(11×c)-a-b))+c←19|y)÷543
+/(10*4 2 0)×y,(3+i>31),(61⍴⍳31)[i←e+28-c] 

Prendendo i casi di prova originali:

      E 2013
20130331
      E 1583
15830410
      E 3029
30290322
      E 1789
17890412         

0

Fortran (GFortran) , 179 byte

READ*,I
J=I/100*2967-I/400*8875+7961
K=MOD(MOD(I,19)*6060+(MOD(MOD(J/25,59),30)+23)*319-1,9570)/330
L=K+28-MOD(I*5/4+J+K,7)
WRITE(*,'(I7,I0.2,I0.2)')I,(L-1)/31+3,MOD(L-1,31)+1
END

Provalo online!

Utilizza l'algoritmo "Pasqua gregoriana emessa" (Al Petrofsky) dal secondo collegamento di risorse. Stranamente, fallisce per l'anno 5701583 (e, apparentemente, solo per quest'anno), predicendo la Pasqua come una settimana prima. Stampa la data in YYYYYYYMMDDformato, con alcuni spazi iniziali se l'anno ha meno di sette cifre.

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.