
今天无意中发现了一个很有奥妙的小玩具,它可以用来查询给定日期的礼拜。扭动年份到对应的月份下,就可以查看那个月具体某个日子是星期几。顿时觉得不可思议。
少见多怪的我又开始瞎琢磨原理:于是召唤出了沉睡已久的蔡勒公式以及一系列它的变形。其他不想说,这个玩具表达的公式,看着最接近以下这一个:
C是世纪数减一,y是年份后两位,M是月份,d是日数。1月和2月要按上一年的13月和
14月来算,这时C和y均按上一年取值。
而我更喜欢下面这个容易理解的公式:
Y是年份,M是月份,d是日数。1月和2月要按上一年的13月和14月来算,这时Y按上一年取值。
算出来的数字再次除以7,余数是几就是星期几。比方,余数是0,则为星期日。
这条公式就是个规律,而这个规律竟然是一个古代的聪明蛋提炼总结的。
要推导出它,首先还是需要另一个日期作为定点已知它是星期几,这里隐晦的选择了公元前最后一天12-31是个星期日,作为锚。
再接下来,如果用冗长但是容易理解的算法就是,计算离开那一天有多少个日子。然后再mod 7,余数就可以得到是星期几。
(Y-1)*365+(Y-1)//4-(Y-1)//100+(Y-1)//400+(这一年出头的日子们)
比如写作当日,2022年9月3日,则是

这货能被7除之后余数是6,所以是个星期六。
我把上面的计算叫做逻辑本身的叙述;特点就是,计算过程就是在直白的说事情。接下来才是数学的变态,人家称呼这些个变形简化叫做数学之美。
一定牢记,这个算法的根本就是找出7的余数是多少。那么为了优雅简化(数学的变态部分),这个说事儿的逻辑开始被找规律从而再次简化:
(Y-1)*365 = (Y-1)*(364+1) #因为364=52*7
进一步得:52*7*(Y-1) + (Y-1); 那么这里 其实我只要(Y-1)//7,因为前面是肯定能被7整除的,就直接扔掉了。
剩下因为闰年,因为100年不是闰年,但是400年又是闰年,这一系列要累积天数的式子,中心思想都是数字7取整简化。

再接下来,就到了要计算这一年出头的日子,我们开始看每个月的规律。首先记得这个月如果能被7整除,那么就是完整的礼拜周期。我们知道在30边上晃悠的且7可以整除的数字是28,那么就有,
| 月份 | 1月 | 2月 | 3月 | 4月 | 5月 | 6月 | 7月 | 8月 | 9月 | 10月 | 11月 | 12月 |
| 月余7 | 3 | 0或1 | 3 | 2 | 3 | 2 | 3 | 3 | 2 | 3 | 2 | 3 |
| 月余7的累积 | 3 | 3或4 | 6或7 | 8或9 | 11或12 | 13或14 | 16或17 | 19或20 | 21或22 | 24或25 | 26或27 | 29或30 |
到了这里,可以看到3-12月,10个月连续稳定,一共26个日子。要分的更细,就会在3月到12月看到两个32323。一月和二月的余数放去尾巴那里,变为13月和14月,其实就是看成序号13和序号14。但是年份上就要算为是上一年序号的。这里会有这个企图的原因是2月的不确定性,如果可以把它当做最后一个月,就不需要去做分情况讨论平年和闰年,式子的未知变量会更少。
| 3月 | 4月 | 5月 | 6月 | 7月 | 8月 | 9月 | 10月 | 11月 | 12月 | 13月(即下一年1月) | 14月(即下一年2月) |
| 3 | 2 | 3 | 2 | 3 | 3 | 2 | 3 | 2 | 3 | 3 | 余下什么都无所谓 |
| 3 | 5 | 8 | 10 | 13 | 16 | 18 | 21 | 23 | 26 | 29 |
请记住,因为这件事情本身就是在找从公元前最后一个日子至今的日子和7的整除关系,所以当把1,2月搬到一年的尾部,从而方便算累积超过28的日子是可以的。虽然看着怪抽象怪恶心,但本质就是会遵循遇7归0这个事儿。年份部分被7挤出来的日子,在上面已经都算好了。
本年那些可以被7整除的部分都不在考虑后,就剩下被挤出的每个月底的多余和当月:

这里可以理解成利用向下取整运算实现这个 13天累积出来对应5个连续月的循环。这个1月也就是13月好巧不巧,也是个3,也就是这串稳定的28有余的两段循环(32323 32323)的下一次循环开始那个位置,而没有破坏它。2月也就是14月又已经到了头。
题外话,这个accumulated部分,我始终觉得有那么点得到答案推算式的意思。因为毕竟只要让M在[3,14]之间是说得过去的,也就可以了。毕竟这算是一个现实世界里面的局限算法而已,并不是个纯数学问题。
末了,之前那些年被7挤出的日子和今年里面被7挤出的日子又放一起,被7再除一下:
感叹一下,带perpetual calendar的机械手表买买可不便宜,但是它的底层逻辑居然可以靠一个几块钱的手工玩具来表达,是多么有意思啊。最上面的玩具图片,从它的盘面也能看出,它在不停的mod 7 mod 4。我是实在没本事花时间再把玩具本身的运作讲彻底了,遗憾。
感受到了此刻,理解力与表达力两种能力上限。