| Bytes | Lang | Time | Link |
|---|---|---|---|
| 962 | Bespoke | 250827T004635Z | Josiah W |
| 210 | C# | 250417T081532Z | juanferr |
| 147 | APLNARS | 250412T181227Z | Rosario |
| 134 | Javascript 134 Characters | 210216T165250Z | Mohsen A |
| 179 | Fortran GFortran | 180329T220820Z | rafa1111 |
| 145 | Javascript | 131205T120437Z | Eliseo D |
| 085 | GolfScript | 130410T224331Z | Peter Ta |
| 119 | Python 2 | 130408T182109Z | Steven R |
| 106 | dc | 130408T194920Z | Fors |
| 154 | PHP | 130405T172543Z | jdstanko |
| 132 | APL | 130408T100636Z | Graham |
| 148 | C | 130407T141838Z | Fors |
Bespoke, 962 bytes
PUT XXX:I FOUR INTEIGHT
INPUT N
DO COPY
OUTPUT N
PUSH I H V
OUTPUT N
DO COPY
PUT XXX:I NUMBERZERO NUMBERZERO;STACKTOP QUOTIENTOF
DO COPY
PUT XXXX:I FOUR INTEIGHT TRI;STACKTOP PRODUCTOF
DO SWITCH
PUSH FOUR STACKTOP QUOTIENTOF
PUT XXXX:BI BI BI FIFTH;STACKTOP PRODUCTOF
STACKTOP MINUS
PUT XXXX:BI SEXTET I TRI;STACKTOP PLUS
DO COPY
PUT XX:BI FIFTH;STACKTOP QUOTIENTOF
PUT XXX:TRI I DIGITNINE;STACKTOP PRODUCTOF
PUSH TRI DO COPYN
PUT XX:I DIGITNINE;STACKTOP MODULO
PUT XXXX:TRI FIFTH I NUMBERZERO;STACKTOP PRODUCTOF
STACKTOP PLUS
PUT XXX:TRI TRI NUMBERZERO;STACKTOP QUOTIENTOF
PUT XX:BI DIGITNINE;STACKTOP MODULO
DO COPY
PUSH FOUR DO ROT
STACKTOP MINUS
DO SWITCH
PUSH FIFTH STACKTOP PRODUCTOF
PUSH FOUR STACKTOP QUOTIENTOF
STACKTOP PLUS
PUSH SEVENTH STACKTOP MODULO
STACKTOP PLUS
STACKTOP MINUS
DO COPY
PUT XX:TRI I;STACKTOP QUOTIENTOF
PUT XXX:I NUMBERZERO NUMBERZERO;STACKTOP PRODUCTOF
DO SWITCH
PUT XX:TRI I;STACKTOP MODULO
STACKTOP PLUSONE
STACKTOP PLUS
OUTPUT N
Outputs in the format YYYYMMDD. A port of the following Easter calculation function from Al Petrofsky:
function Easter20ops(YR) {
var a = ~~(YR / 100) * 1483 - ~~(YR / 400) * 2225 + 2613;
var b = ~~((YR % 19 * 3510 + ~~(a / 25) * 319) / 330) % 29;
return 56 - b - (~~(YR * 5 / 4) + a - b) % 7;
// To get Month & Day in 23 total arithmetic operations, use:
// c = 148 - b - (~~(YR * 5 / 4) + a - b) % 7;
// Month = ~~(c / 31);
// Day = c % 31 + 1;
}
C#, 212 210 bytes
int y=int.Parse(args[0]),a=y%19,b=y/100,h=(19*a+b-b/4-(8*b+13)/25+15)%30,l=(32+2*(b%4)+2*(y%100/4)-h-(y%100%4))%7,m=(a+11*h+19*l)/433,n=(h+l-7*m+90)/25;Console.WriteLine($"{y}{n:D2}{(h+l-7*m+33*n+19)%32:D2}");
Try it on JDoodle
Ungolfed:
int y = int.Parse(args[0]),
a = y % 19,
b = y / 100,
h = (19 * a + b - b / 4 - (8 * b + 13) / 25 + 15) % 30,
l = (32 + 2 * (b % 4) + 2 * (y % 100 / 4) - h - (y % 100 % 4)) % 7, m = (a + 11 * h + 19 * l) / 433, n = (h + l - 7 * m + 90) / 25;
Console.WriteLine($"{y}{n:D2}{(h + l - 7 * m + 33 * n + 19) % 32:D2}");
First statement declares and calculates most variables. Second statement calculates the day, formats and prints the result. It uses the 1961 New Scientist algorithm from Wikipedia.
Edit: -2 bytes thanks for @Themoonisacheese
APL(NARS), 147 chars
{{(m n o)←{2≤≢⍵:⍵⋄'0',⍵}¨⍕¨⍵⋄m,'-',n,'-',o}⍵,(⌊r÷31),1+31∣r←148-r+7∣(⌊⍵×5÷4)+a-r←29∣⌊((319×⌊25÷⍨a←2613+(1483×⌊⍵÷100)-(2225×⌊⍵÷400))+3510×19∣⍵)÷330}
I just copied the text, I say it was need years/generations for make something as above...Input one integer, output one data, the Easter date.
test
E←{{(m n o)←{2≤≢⍵:⍵⋄'0',⍵}¨⍕¨⍵⋄m,'-',n,'-',o}⍵,(⌊r÷31),1+31∣r←148-r+7∣(⌊⍵×5÷4)+a-r←29∣⌊((319×⌊25÷⍨a←2613+(1483×⌊⍵÷100)-(2225×⌊⍵÷400))+3510×19∣⍵)÷330}
E 5701583
5701583-04-10
E 2013
2013-03-31
E 1583
1583-04-10
E 3029
3029-03-22
E 1789
1789-04-12
E 1725
1725-04-01
I have some duoubit for the date E 3029, here with one other program (change hacking above for use 'my' moon phase program) result
H3 3029
3029 4 19
so a different data from above...This below is the [phase], [days to next new moon] result to me for 20 3 3029
H 20 3 3029
5 10
{H ⍵ 3 3029}¨15..30
4 15 4 14 4 13 4 12 5 11 5 10 5 9 5 8 6 7 6 6 6 5 6 4 7 3 7 2 7 1 7 0
15 16 17 18 19 20 | 21 21 22
so full moon has to be where there is phase 4, but it seems before 20 3 3029, and in the definition of Easter day i read "Domenica successiva alla prima luna piena di primavera". Possible H and H3 are not accurate enought can make errors of +-1.... Even if my function not agree with that too, in this link
https://moonphases.org/fullmoons/3029
result full moon for 22-03-3029 so 22-03 is not the date of Easter in 3029 because the date of Easter would be after the date [the date or the time? because change the day] of the first full moon.
Javascript 134 Characters
Using a slightly modified Al Petrofsky's 20-op algorithm to allow a simpler conversion into the year-month-date format.
This provides additional 14 characters shorter code from the answer provided by WallyWest
The Original Al Petrofsky's Code:
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;
Last line changed to:
d =148-c-~(a-b+c-24-Y/.8)%7;
1. 138 Characters With the format YYYY-MM-DD
e=y=>(c=(y%19*351-31.9*~((b=(a=y/100|0)>>2)+29.32*a+13.54))/33%29|0,d=148-c-~(a-b+c-24-y/.8)%7,y+'-0'+(d/31|0)+"-"+((o=d%31+1)>9?o:'0'+o))
console.log(e(2021));
console.log(e(2022));
console.log(e(5701583));
console.log(e(2013));
console.log(e(1583));
console.log(e(3029));
console.log(e(1789));
console.log(e(1725));
2. 134 Characters With the format YYYYMMDD
e=y=>(c=(y%19*351-31.9*~((b=(a=y/100|0)>>2)+29.32*a+13.54))/33%29|0,d=148-c-~(a-b+c-24-y/.8)%7,y+'0'+(d/31|0)+((d=d%31+1)>9?d:'0'+d))
console.log(e(2021));
console.log(e(2022));
console.log(e(5701583));
console.log(e(2013));
console.log(e(1583));
console.log(e(3029));
console.log(e(1789));
console.log(e(1725));
Fortran (GFortran), 179 bytes
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
Uses the "Emended Gregorian Easter" algorithm (Al Petrofsky) from the second resource link. Strangely, it fails for year 5701583 (and, apparently, only for this year), predicting the Easter as one week earlier. Prints the date in YYYYYYYMMDD format, with some leading spaces if the year has less then seven digits.
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))}
Inspired by @jdstankosky's PHP solution... Provides YYYYMMDD result...
Now narrowed down to:
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))
Now asks for input... reduced literal string of "0" to 0 and let loose typing work to my advantage! :)
Reduced further to take ES6 into account...
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)
GolfScript (85 chars)
~:^100/.)3*4/.@8*13+25/-^19%.19*15+@+30%.@11/+29/23--.@-^.4/++7%97--^0@.31/100*\31%)+
Sample usage:
$ golfscript.rb codegolf11132.gs <<<2013
20130331
Note that this uses a different algorithm to most of the current answers. To be specific, I've adapted the algorithm attributed to Lichtenberg in the resource linked by Sean Cheshire in a comment on the question.
The original algorithm, assuming sensible types (i.e. not JavaScript's numbers) and with an adaptation to give month*31+day (using day offset of 0) is
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
I extracted a common subexpression and did some other optimisations to reduce to
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
This approach has slightly more arithmetic operations than the other one (Al Petrofsky's 20-op algorithm), but it has smaller constants; GolfScript doesn't need to worry about the extra parentheses because it's stack-based, and since each intermediate value in my optimised layout is used precisely twice it fits nicely with GolfScript's limitation of easy access to the top three items on the stack.
Python 2 - 125 120 119 chars
This is Fors's answer shamelessly ported to 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
Edit: Changed last line from print"%d-0%d-%02d"%(y,b/31,b%31+1) to save 5 characters. I would have loved to represent 10000 as 1e4, but that would produce floating point necessitating a call to int.
Edit2:
Thanks to Peter Taylor for showing how to get rid of that 10000 and save 1 character.
dc: 106 characters
?[0n]smdndsy100/1483*ly400/2225*-2613+dsa25/319*ly19%3510*+330/29%sb148lb-5ly*4/la+lb-7%-d31/0nn31%1+d9>mp
Usage:
> 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
>
This should be able to be shortened by using 'd' and 'r' instead of all the loads and stores.
PHP 154
150 chars if I switch to YYYYMMDD instead of YYYY-MM-DD.
<?$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";
With Line Breaks:
<?
$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";
Useage: php easter.php 1997
Output: 1997-03-30
Useage: php easter.php 2001
Output: 2001-04-15
APL 132
This algorithm calculates the number of days Easter lies relative to the beginning of March. The date is returned in the YYYYMMDD format as allowed in the question:
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]
Taking the original test cases:
E 2013
20130331
E 1583
15830410
E 3029
30290322
E 1789
17890412
C: 151 148 characters
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);}
And the same code, but better formatted:
#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);
}
There are frightfully many algorithms for calculating the date of Easter, but only a few of them are well suited for code golfing.