欢迎光临散文网 会员登陆 & 注册

机械万年历的数学原理

2023-02-08 08:55 作者:shaleone  | 我要投稿

话题:#数学# #万年历#

小石头/编


逢年过节,人们难免会送一些小礼物,这里面就有一种机械万年历,

虽然说是万年历,但实际上只有几十年,可即便如此,也是设计的非常精妙。


机械万年历是月历。传统的月历,是一张以星期为表头的表格,日期被填入的 5×7 格子中,

这里,不同月份之间,表头是固定的,变化的是日期位置。日期位置的变化不利于机械实现,于是,我们让 日期位置不变,反过来,调整表头中的星期,得到,

观察发现:

  • 若 以大月31天为准(多出来的做冗余量),则 不同月份的日期是同一个4×7格子;

  • 若 将表头中星期向两边无限延伸,则 不同月份 得到的是同一个无线列;

这样一来,不同月份之间,只是 日期格子 与 星期列 之间的 相对位置 不同而已,接下来需要做的是确定这个 “定位”,也就是 确定 每月1日 是星期几。


设 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天,这导致 上表 三到十二月 都要向后移动一格,这很不划算,于是,可以考虑 保持  三到十二月 不变 让 一二月 向前 移动 一格,即,

  • 闰年一月1日 是 星期 a - 1 ≡ a + 6 (mod 7);

  • 闰年二月1日 是 星期 a+3 - 1 = a + 2 (mod 7);

因为,只有两个月发生改变,没必要新做一张新表,  可以用记号标出 加入上表中,于是得到:

至此,我们就确定了任何一年内,每个月1日的星期定位,月份表内各月的定位固定,不同的是月份表在年份列上的定位。


接下来,我们需要确定每一年第1天的星期,

  • 若 A 是平年,则有 365天,由 356 mod 7 = 1,知道 A+1年的 第1天 是 星期 a+1;

  • 若 A 是润年,则多 1天,因此 A+1年的 第1天 是 星期 a+2;

于是我们得到:

通过 这个 表,我们可以 将 定位 年份列 的 月份表 就和 定位 星期列 的 日期表 关联起来,以 2023年 为准,有:

我们发现 月份表每月关于 年的定位 和 对应月 日期表关于 星期列 的定位 刚好相反,于是可以考虑 中心对称 圆盘 将 月份表 和 日期表 整合在一起,得到:

另外,无限星期列 可以 通过 圆环 来实现,然后 圆环和圆盘 同圆心,以方便定位。为了让星期首位相连,圆环分割数必须是 7 的倍数,为了能 能容纳 下 月份表 和 日期表,圆盘 分割数必须大于 7 + 7 = 14,因为要对齐定位,圆环 和 圆盘 分割数 必须相同,这里选择 4×7 = 28 的分割方案。

我们的万年历,从 2023年 开始,由于 2023年 第一天 是 星期日,将 2023年 与 月份表 一月列 对齐, 将 星期日 与  日期表 1日列 对齐,然后按照 逆时针 依次填满 星期环列,就得到上图。这样,当对齐 月份和 年份,日期表 刚好 对于 正确的 星期。

然后,需要将 2023 年之后的年份 填上,由于 星期时逆时针,故 年份 也需要按照 逆时针 排列,于是 就得到上图。


当定位到闰年时,例如:2024年,

这时月份表使用的是润一月,于是修改年份位置,让年份 对位「一月」列,这 需要 让年份位置 从 月表 的 a 列 变为 a+6列,即,顺时针挪6位,这距离不仅有点大,而且 会和该位置 的年份冲突,例如:对应 2024年 调整 后与 2041年 冲突。考虑到 a+6 ≡ a-1 (mod 7) ,于是  顺时针挪6位 就等于 逆时针挪1位,而刚好 润年导致 之后有一个空位!

按照这个分析,将所有闰年 都 逆时针挪1位,并标上 闰年标志 以和 闰月匹配,这样就得到如下结果:

最后,我们发现,年份环列上,还有6个空格,我们需要将 后续  2045 - 2050 年补上。为了方便,我们将 2023年的位置 设为 0,这样第一个空格位置就是 1,所有空位 为 5y+1。

2045年本来的位置在 2023年位置 0 处,这有冲突需要调整,由于要保持星期对应,故调整位置必须是 7x+0,于是可列出 不定方程:

7x + 0 = 5y + 1

解方程 得到  y=1(x=1),这说明可将 2045年调整到 第2个空位处。其它年份也可以用类似的方法计算,不过比较麻烦,于是可以反过来,由 空格求出 适合年份,有,

1 mod 7 = 1 ⇒ 46

(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

我们发现,这 其中 刚好 缺少 偏移 3 这个空位,于是 6 个空格 完美的对应 剩下的 6 个年份。按照这个结果,修改后得到:

这样,最终我们得到 2023—2050年,机械万年历的完整版本。

当然,也可以将年份设计为两层,这样可以再 容纳 2051—2078年的日历,大家有兴趣不妨试一试!


机械万年历的数学原理的评论 (共 条)

分享到微博请遵守国家法律