Skip to content

Instantly share code, notes, and snippets.

@madrobby
Created March 30, 2013 13:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save madrobby/5276743 to your computer and use it in GitHub Desktop.
Save madrobby/5276743 to your computer and use it in GitHub Desktop.
Easter code golfing! Who can make this smaller? Bonus points for fitting it in a tweet. You can use a different algorithm, but it should work for any gregorian date.
// date of easter, call function with the 4-digit year as argument
function (a,b,c,d,e,f,g,h,i,j,k,l,m){return b=a%19,c=~~(a/100),d=a%100,e=~~(c/4),f=c%4,g=~~((c+8)/25),h=~~((c-g+1)/3),i=(19*b+c-e-h+15)%30,j=~~(d/4),k=d%4,l=(32+2*f+2*j-i-k)%7,m=~~((b+11*i+22*l)/451),a+"-"+~~((i+l-7*m+114)/31)+"-"+((i+l-7*m+114)%31+1)}
// f(2013) -> "2013-3-31"
// f(2012) -> "2012-4-8
// f(1775) -> "1775-4-16"
@madrobby
Copy link
Author

Note that the code isn't really optimized and a straight port of a fairly standard algorithm (there's definitely some redundancy and optimization potential!).

Calculating Easter Sunday has a long and convoluted history, for more information see http://en.wikipedia.org/wiki/Computus.

Here's a version to play with: http://jsfiddle.net/FdCPD/

@jsjohnst
Copy link

The shortest I've come up with (and what I would argue is the shortest possible, give or take a couple characters, that will work for all dates) is 195 characters. It's a straight evolution from your original, just simplifying all the calculations as much as possible. I also came up with a neat trick to cut out the "-" hardcoded strings by negating the value used to calculate the month and date values (see the negation at the beginning of line 4 and the -1 rather than +1 in the return on line 5).

My version is:

function(y,a,b){return a=~~(y/100),b=(19*(y%19)+a-~~(a/4)-~~((a-~~((a+8)/25)+1)/3)+15)%30,a=(32+2*(a%4)+2*~~(y%100/4)-b-y%100%4)%7,a=-(b+a-7*~~((y%19+11*b+22*a)/451)+114),''+y+~~(a/31)+(a%31-1);}

A slightly more readable version with whitespace (and semicolons, I hate leaving them off) restored and with a little reformatting of the order for clarity in what the return does is:

function (y, a, b) {
  a = ~~(y / 100);
  b = (19 * (y % 19) + a - ~~(a / 4) - ~~((a - ~~((a + 8) / 25) + 1) / 3) + 15) % 30;
  a = (32 + 2 * (a % 4) + 2 * ~~( y % 100 / 4) - b - y % 100 % 4) % 7;
  a = -(b + a - 7 * ~~((y % 19 + 11 * b + 22 * a) / 451) + 114);
  return '' + y + ~~(a / 31) + (a % 31 - 1);
}

The Fiddle is available here: http://jsfiddle.net/jjFh3/

@jsjohnst
Copy link

Take that back, guess I missed something. Here's 194. :)

function(y,a,b){return a=~~(y/100),b=(19*(y%19)+a-~~(a/4)-~~((a-~~((a+8)/25)+1)/3)+15)%30,a=(32+2*(a%4)+2*~~(y%100/4)-b-y%100%4)%7,a=b+a-7*~~((y%19+11*b+22*a)/451)+114,''+y+~~(-a/31)+(-a%31-1)}

Fiddle: http://jsfiddle.net/uAKZH/

@jsjohnst
Copy link

And here is 191...

function(y,a,b){a=y/100|0;b=(19*(y%19)+a-(a/4|0)-((a-((a+8)/25|0)+1)/3|0)+15)%30;a=(32+2*(a%4)+2*(y%100/4|0)-b-y%100%4)%7;a=b+a-7*((y%19+11*b+22*a)/451|0)+114;return ''+y+(-a/31|0)+(-a%31-1)}

Fiddle: http://jsfiddle.net/A8caW/

@codepunkt
Copy link

142 characters, based on a different algorithm (taken from http://www.merlyn.demon.co.uk/estralgs.txt)

function(y){var 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;return[y,3+d/32|0,d%31||31].join('-')}

Fiddle: http://jsfiddle.net/gonsfx/QW3DP/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment