機械萬年歷的數(shù)學(xué)原理
話題:#數(shù)學(xué)# #萬年歷#

逢年過節(jié),人們難免會送一些小禮物,這里面就有一種機械萬年歷,

雖然說是萬年歷,但實際上只有幾十年,可即便如此,也是設(shè)計的非常精妙。
機械萬年歷是月歷。傳統(tǒng)的月歷,是一張以星期為表頭的表格,日期被填入的 5×7 格子中,

這里,不同月份之間,表頭是固定的,變化的是日期位置。日期位置的變化不利于機械實現(xiàn),于是,我們讓 日期位置不變,反過來,調(diào)整表頭中的星期,得到,

觀察發(fā)現(xiàn):
若 以大月31天為準(多出來的做冗余量),則 不同月份的日期是同一個4×7格子;
若 將表頭中星期向兩邊無限延伸,則 不同月份 得到的是同一個無線列;

這樣一來,不同月份之間,只是 日期格子 與 星期列 之間的 相對位置 不同而已,接下來需要做的是確定這個 “定位”,也就是 確定 每月1日 是星期幾。
設(shè) A 年的 第一天 是 星期 a,即,
一月1日 是 星期 a;
然后,日期 每 增加7天,星期 又回到 a,也就是 a + 7 ≡ a (mod 7),而 一月是 31天,于是 可計算出,
二月1日 是 星期 a + (31 ?mod 7) ?= ?a+3 (mod 7);
接著,可依次算出,
三月1日 是 星期 a+3 + (28 mod 7) = a+3 (mod 7);
四月1日 是 星期 a+3 + (31 mod 7) ?= a+6 (mod 7);
五月1日 是 星期 a+6 + (30 mod 7) = a+8 ≡ a+1 (mod 7);
六月1日 是 星期 a+1 + (31 mod 7) = a+4 (mod 7);
七月1日 是 星期 a+4 + (30 mod 7) = a+6 (mod 7);
八月1日 是 星期 a+6 + (31 mod 7) = a+9 ≡ a+2 (mod 7);
九月1日 是 星期 a+2 + (31 mod 7) = a+5 (mod 7);
十月1日 是 星期 a+5 + (30 mod 7) = a+7 ≡ a (mod 7);
十一月1日 是 星期 a + (31 mod 7) = a+3 (mod 7);
十二月1日 是 星期 a+3 + (30 mod 7) = a+5 (mod 7);
這樣就得到了一張表:

這里需要注意,以上 考慮的是 平年的情況,若 ?A 是閏年,則 二月 會多1天,這導(dǎo)致 上表 三到十二月 都要向后移動一格,這很不劃算,于是,可以考慮 保持 ?三到十二月 不變 讓 一二月 向前 移動 一格,即,
閏年一月1日 是 星期 a - 1 ≡ a + 6 (mod 7);
閏年二月1日 是 星期 a+3 - 1 = a + 2 (mod 7);
因為,只有兩個月發(fā)生改變,沒必要新做一張新表, ?可以用記號標出 加入上表中,于是得到:

至此,我們就確定了任何一年內(nèi),每個月1日的星期定位,月份表內(nèi)各月的定位固定,不同的是月份表在年份列上的定位。

接下來,我們需要確定每一年第1天的星期,
若 A 是平年,則有 365天,由 356 mod 7 = 1,知道 A+1年的 第1天 是 星期 a+1;
若 A 是潤年,則多 1天,因此 A+1年的 第1天 是 星期 a+2;
于是我們得到:

通過 這個 表,我們可以 將 定位 年份列 的 月份表 就和 定位 星期列 的 日期表 關(guān)聯(lián)起來,以 2023年 為準,有:

我們發(fā)現(xiàn) 月份表每月關(guān)于 年的定位 和 對應(yīng)月 日期表關(guān)于 星期列 的定位 剛好相反,于是可以考慮 中心對稱 圓盤 將 月份表 和 日期表 整合在一起,得到:

另外,無限星期列 可以 通過 圓環(huán) 來實現(xiàn),然后 圓環(huán)和圓盤 同圓心,以方便定位。為了讓星期首位相連,圓環(huán)分割數(shù)必須是 7 的倍數(shù),為了能 能容納 下 月份表 和 日期表,圓盤 分割數(shù)必須大于 7 + 7 = 14,因為要對齊定位,圓環(huán) 和 圓盤 分割數(shù) 必須相同,這里選擇 4×7 = 28 的分割方案。
我們的萬年歷,從 2023年 開始,由于 2023年 第一天 是 星期日,將 2023年 與 月份表 一月列 對齊, 將 星期日 與 ?日期表 1日列 對齊,然后按照 逆時針 依次填滿 星期環(huán)列,就得到上圖。這樣,當(dāng)對齊 月份和 年份,日期表 剛好 對于 正確的 星期。
然后,需要將 2023 年之后的年份 填上,由于 星期時逆時針,故 年份 也需要按照 逆時針 排列,于是 就得到上圖。
當(dāng)定位到閏年時,例如:2024年,

這時月份表使用的是潤一月,于是修改年份位置,讓年份 對位「一月」列,這 需要 讓年份位置 從 月表 的 a 列 變?yōu)?a+6列,即,順時針挪6位,這距離不僅有點大,而且 會和該位置 的年份沖突,例如:對應(yīng) 2024年 調(diào)整 后與 2041年 沖突。考慮到 a+6 ≡ a-1 (mod 7) ,于是 ?順時針挪6位 就等于 逆時針挪1位,而剛好 潤年導(dǎo)致 之后有一個空位!
按照這個分析,將所有閏年 都 逆時針挪1位,并標上 閏年標志 以和 閏月匹配,這樣就得到如下結(jié)果:

最后,我們發(fā)現(xiàn),年份環(huán)列上,還有6個空格,我們需要將 后續(xù) ?2045 - 2050 年補上。為了方便,我們將 2023年的位置 設(shè)為 0,這樣第一個空格位置就是 1,所有空位 為 5y+1。
2045年本來的位置在 2023年位置 0 處,這有沖突需要調(diào)整,由于要保持星期對應(yīng),故調(diào)整位置必須是 7x+0,于是可列出 不定方程:
7x + 0 = 5y + 1
解方程 得到 ?y=1(x=1),這說明可將 2045年調(diào)整到 第2個空位處。其它年份也可以用類似的方法計算,不過比較麻煩,于是可以反過來,由 空格求出 適合年份,有,

(5×1+1) mod 7 = 6 ? 50
(5×2+1) mod 7 = 4 ?「48」
(5×3+1) mod 7 = 2 ? 47
(5×4+1) mod 7 = 0 ? 45
(5×5+1) mod 7 = 5 ? 49
我們發(fā)現(xiàn),這 其中 剛好 缺少 偏移 3 這個空位,于是 6 個空格 完美的對應(yīng) 剩下的 6 個年份。按照這個結(jié)果,修改后得到:

這樣,最終我們得到 2023—2050年,機械萬年歷的完整版本。
當(dāng)然,也可以將年份設(shè)計為兩層,這樣可以再 容納 2051—2078年的日歷,大家有興趣不妨試一試!
