This post will be about psychology as much as math, looking at a number of algorithms for mentally calculating the same function.
The most difficult part of mentally computing days of the week is computing
⌊5y/4⌋ % 7
where y is the last two digits of a year. This quantity is called the year share because it is the year’s contribution to the day-finding algorithm.
The most obvious way to compute this function is to take the whole number part of y/4, add it to y, and take the remainder when dividing by 7. In Python, this would be
def method0(y): return (y + y//4) % 7
The only reason there’s more to say is that the ease of description is not the same as ease of execution. There are several other methods that some people find easier to use.
Outline
In [1] the author gives several methods for computing the year share. Each of these methods has some advantage over the most direct approach. They generally work with smaller numbers and take advantage of operations that are mentally trivial such as splitting a number into its tens and ones digits.
I’ll describe one of these methods in words, the so-called “odd + 11” method, then implement all the methods in Python. Each method looks more complicated than the direct method if you just glance at the code. But if you mentally execute the code you can see why each method could be easier for a human to carry out.
You can find algebraic proofs of why each method works in [1]. Here I’ll use brute force: the methods only have to work for integer values of y from 0 to 99, so I’ll let Python verify that the methods all produce the same result. This brute force approach uncovered an error in the the paper that I correct in the code below.
Odd + 11 method
Here’s the “odd + 11” method:
- If y is odd, add 11 to y.
- Divide y by 2.
- If y is odd after the step above, add 11.
- Set y to the remainder when dividing y by 7.
- Return 7 − y.
This method requires adding no more than 11, and it only requires one mental “register.” That is, all operations are done in place. With the direct method, you have to hold y and ⌊y/4⌋ in your head.
Python implementations
Here are Python implementations of 10 methods of computing a value congruent to ⌊5y/4⌋ mod 7. That is, the methods may produce different values, but the values differ by multiples of 7.
Note that the last three methods only require working with single-digit numbers.
Method #6 may be the easiest method to use. YMMV. (Update: See this follow-on post about this method.)
from math import floor def method0(y): return y + y//4 def method1(y): if y % 2 == 1: y += 11 y /= 2 if y % 2 == 1: y += 11 y %= 7 return 7 - y def method2(y): parity1 = y % 2 if parity1: y -= 3 y /= 2 parity2 = y % 2 if parity1 != parity2: y -= 3 return -y def method3(y): t = y % 12 return y // 12 + t + t//4 def method4(y): r = y % 4 y -= r return r - y//2 def method5(y): # placeholder to maintain the numbering in the paper return method0(y) def method6(y): r = y % 4 y -= r # i.e. latest leap year t = y // 10 u = y % 10 return 2*t - u//2 + r def method7(y): t = y // 10 u = y % 10 x = (2*t + u) // 4 x += u # The paper says to return 2t - x but it should be the opposite. return x - 2*t def method8(y): t = y // 10 u = y % 10 p = t % 2 return (2*t + 10*p + u + (2*p + u)//4) % 7 def method9(y): t = y // 10 u = y % 10 return u - t + floor(u/4 - t/2) # verify all resultss are equal mod 7 for y in range(100): for m in range(10): f = eval("method" + str(m)) assert ((method0(y) - f(y)) % 7 == 0)
Related posts
- Mentally calculating the day of the week
- What use is mental math now?
- 100 digits worth memorizing
- Mentally calculating common functions
[1] S. Kamal Abdali. inding the year’s share in day-of-week calculations. Recreational Mathematics Magazine. Number 6, December 2016.
Here’s a method that is not on your list (and one I haven’t seen anywhere else). If the year share y is a multiple of 4, then 5/4*y mod 7 is the same as 3y mod 7 since the multiplicative inverse of 4 modulo 7 is 2 and 5*2 is equivalent to 3. So whenever the year is a multiple of 4, just calculate 3y mod 7. If the year is not a multiple of 4, then let r = y % 4, and find 3(y-r)+r mod 7.
BTW, it looks like reference [1] is missing. Maybe I just missed it?
Thanks. I forgot to add my footnote. Just updated the post.