Here's a summary of the methods I know for computing the factor based on the last two digits of the year that gets added to the factor from the century number to get the Doomsday for the year.<p>Notation: "A // B" is integer vision (think Python 3 // operator). "A, B = C /% D" means that "A = C//D" and "B = C % D". "A ≡ B" means A and B are the same mod 7. "A ≡⁴ B" means A and B are the same mod 4. I'll use x for multiplication. X + <a,b,c,d> means the four values A+a, X+b, X+c, X+d.<p>Let Y be the last two digits of the year.<p>Observation: 365 ≡ 1. If it weren't for leap years, the year factor would simply go up by 1 each year. A leap year pushes the start of the next year back a day, and that's cumulative, so we need a correction of the number of leap years that have past.<p>1. That gives the first, and simplest, way to compute the year factor for year Y.<p><pre><code> return Y + Y//4
</code></pre>
Advantage: simplest algorithm.<p>Disadvantage: numbers get larger than you might be comfortable with for fast mental meth. Doing 99, for example, gives 99 + 99/4 = 99 + 24 = 123 ≡ 4, which has plenty of opportunity along the way to goof.<p>Many people will do better with a method that uses a little more complicated algorithm but cuts down the size of the numbers.<p>2. The divide by 12 method, which is the one given in the article, does this.<p><pre><code> a, b = Y /% 12
c = b // 4
return a + b + c
</code></pre>
Here's why it works.<p><pre><code> Y = 12 a + b
Y//4 = 3 a + b//4
= 3 a + c
Y + Y//4 = 15 a + b + c
≡ a + b + c
</code></pre>
Advantage: a <= 8, b < 12, c < 4. Other than the first /%, you only deal with fairly small numbers.<p>Disadvantage: Still easy for many people to goof on the initial /%.<p>Note: if you divide by 20 instead of 12, you get a similar method, except that you'll need to use 4a instead of a. Since a is at most 4, 4a is not large. For many people %/ 20 might be sufficiently easier to deal with in mental math than %/ 12 that it is worth the cost of having to multiply by 4.<p>3. The odd 11 method.<p><pre><code> Y += 11 if Y is odd
Y //= 2
Y += 11 if Y is odd
return -Y
</code></pre>
The easiest way to see that this works is to go back to Y + Y//4. Write Y = 4q + r, where r = 0, 1, 2, or 3.<p>The first conditional add 11 step turns 4q + <0,1,2,3> into 4q + <0,12,2,14>. Dividing by 2 then gives 2q + <0,6,1,7>. The second conditional add 11 gives 2q + <0,6,12,18>. Negating mod 7 gives 5q + <0,1,2,3>, which is 4q + <0,1,2,3> + q = Y + Y//4.<p>Similar considerations give other divide by 2 and negate methods. If you note that if Y = 4q, then Y + Y//4 ≡ -(Y//2), then it is just a matter of how to take into account the r in 4q + r when r != 0. One way to do that would be first subtract r, then do the -(Y//2), and then add r back. That works because none of the r != 0 years are leap years, and so we just need to add 1 for each of them.<p>Another way would be to just go ahead and do -(Y//2), and then add in a correction based on r. Let Y = 4q + <0,1,2,3>. Then -(Y//2) ≡ 5q + <0,0,-1,-1>. We want 5q + <0,1,2,3>, so we have to add 0, 1, 3, or 4 if r = 0, 1, 2, 3, respectively.<p>That last correction can be split into two parts: add 1 if Y is odd, plus add 2 if Y//2 is odd. That gives:<p><pre><code> t = Y odd ? 1 : 0
Y //= 2
t += 3 if Y is odd
return -Y + t
</code></pre>
4. The method I actually use, which views the two digit year as a decade part and a year within the decade part, and operates on them separately. Since I gave a long description of it yesterday, I'll just link to that [1] here.<p>[1] <a href="https://news.ycombinator.com/item?id=21926543" rel="nofollow">https://news.ycombinator.com/item?id=21926543</a>