Cleaning up the Easter program

Don't add features to your scientific code (yet); clean it up first

What I like about my Easter calculation program is that it shows how quickly scientific code becomes a mess. Whenever you reach the stage where a program starts giving good results, you say “Yes!” and then you start adding more features, when you should stop and clean the code instead.

In fact, I started to add more features to it before it was even ready. I should have written a purely Gregorian version, but I incorporated Julian before I even started. Now that I understand my mistake I’ll undo it. I’ll just throw away all Julian/Orthodox code, which is about 25% of all code.

The revised function (shown below) is also confusing, but at least it looks almost identical to Gauss’s algorithm (that is, the algorithm is also confusing). My seemingly impossible task is to make the program understandable without comments and without needing to explain it. But before that we need to write some tests, coming in my next post.

function getEasterDate(year) {
  let month;
  let dayOfMonth;

  const a = year % 19;
  const b = year % 4;
  const c = year % 7;
  const k = Math.floor(year / 100);
  const p = Math.floor((13 + 8 * k) / 25);
  const q = Math.floor(k / 4);
  const M = (15 - p + k - q) % 30;
  const N = (4 + k - q) % 7;
  const d = (19 * a + M) % 30;
  const e = (2 * b + 4 * c + 6 * d + N) % 7;
  if (d === 29 && e === 6) {
    month = 4;
    dayOfMonth = 19;
  } else if (d === 28 && e === 6 && (11 * M + 11) % 30 < 19) {
    month = 4;
    dayOfMonth = 18;
  } else {
    month = 3;
    dayOfMonth = 22 + d + e;
    if (dayOfMonth > 31) {
      month = 4;
      dayOfMonth -= 31;
    }
  }
  return [month, dayOfMonth];
}