ルイス・キャロル ― 特定の日付の曜日を計算する技法(1887年)
(futilitycloset.com)- Lewis Carrollは1887年3月31日にNatureへ送った手紙で、任意の日付の曜日を暗算で求める手順を提案している
- 日付を世紀・年・月・日の4項目に分けて足し合わせ、計算の途中ごとに7で割った余りだけを残して複雑さを下げる
- Carrollは自分でも平均して約20秒かかるとし、計算の速い人なら15秒以内でも可能だろうと見ている
- 規則にはOld StyleとNew Styleの違い、うるう年補正、月ごとの項目値が含まれ、最終値は0=Sunday、1=Mondayの順で解釈される
- 例の計算では1783年9月18日はThursday、1676年2月23日はうるう年補正後にWednesdayとなる
日付を4つの項目に分ける方法
- Lewis Carrollは1887年3月31日にNatureへ送った手紙で、特定の日付の曜日を暗算で求める方法を示した
- 入力する日付は4つの部分に分ける
- Century-Item: 年の上2桁
- Year-Item: 世紀以降の年
- Month-Item: 月
- Day-Item: その月の日付
- 各項目を計算して累積合計に足し、項目や合計が7を超えたら7で割った余りだけを保持する
項目ごとの計算規則
-
Century-Item
- Old Styleは1752年9月2日で終わったものとし、世紀の値を18から引く
- New Styleは1752年9月14日に始まったものとし、世紀の値を4で割った余りを3から引いてから2倍する
- たとえば1811年のCentury-Itemには、上2桁の18を使う
-
Year-Item
- 世紀以降の年について、12の個数、残りの値、その残りに含まれる4の個数を足す
-
Month-Item
- 月名が母音で始まる、または母音で終わるなら、その月の年内での順序を10から引く
- これにその月の日数を足すと、翌月の項目値になる
- 7で割ったうえで使う月ごとの値は次のとおり
- January 0, February 3, March 3, April 6, May 1, June 4
- July 6, August 2, September 5, October 0, November 3, December 5
-
Day-Item
- その月の日付そのものを使う
-
うるう年補正
- 日付がうるう年のJanuaryまたはFebruaryなら、最終合計から1を引く
- 合計が0なら、先に7を足してから1を引く
- うるう年は4で割り切れる年だが、New Styleの世紀年では、世紀数が4で割り切れない場合は例外となる
- 例として1800年はNew Styleではこの例外に当たる
- 最終結果は曜日番号として解釈し、0はSunday、1はMondayで、以後順番に対応する
計算例と出典
- 1783年9月18日の計算結果はThursdayである
- 1676年2月23日はうるう年補正を経てWednesdayとなる
- この手順はEdward WakelingのRediscovered Lewis Carroll Puzzles(1995年)を通じて伝えられている
1件のコメント
Hacker News のコメント
この方法は私が使っている方法と非常によく似ていて、Art Benjamin も話してみると似た方法を使っていた。10〜15秒以内にやるのは簡単だが、練習と、ごく少量の暗記、少しの暗算が必要
私は勘を保つためにもよく使っているし、いったん身につけると意外に役に立つ場面が多いので使い続けるようになる。J. H. Conway は別の手法である Doomsday rule を使っていて、今年の日付を計算するときはそちらに切り替えた。より速くて簡単だが、別の年の「Doomsday」を求めるのはより難しいので、そのときは元の方法に戻る
たとえば 2024/05/24 は、2012年以降の12年、うるう年3回、5月の魔法の数字2、日付24を足して mod 7 を取ると
(12+3+2+24)=6、つまり金曜日になる。各月の魔法の数字は144 / 025 / 036 / 146と覚えられ、必要なら原理から計算することもできる144 : Jan, Feb, Marは Jan=1、Feb=4、Mar=4 という意味だと理解すればよい20+5+4+7 ≡ 1なので日曜日を期待したが、実際には土曜日で、2032年がうるう年であり日付が2月29日より前だったためだったこのような場合、つまりうるう年の2月29日より前、またはその当日までは 1 を引く必要がある
0, 1, -1, 0, 0, 1, 1, 2, 3, 3, 4, 4は、各月1日の年内通算日と、それ以前の月がすべて30日だったと仮定した場合の年内通算日との差分であるオフセットたとえば最初の11か月がすべて30日だったなら、12月25日は
30×11+25=355日目で、ここに12番目のオフセット4を足すと実際の359日目になる。このオフセット列は覚えやすく、覚えてしまえば月別の魔法の数字はMagic(n)=2n+Offset(n)+cで得られる1 4 4 0 2 5 0 3 6 1 4 6の魔法の数字ではc=-1で、12月は2×12+4-1 ≡ 6 (mod 7)となる。逆に、覚えた魔法の数字からMagic(n)-2n-cを計算してオフセットも復元でき、オフセットの範囲が[-1,4]であることだけ覚えておけばよい記事を読んでいるうちに、Old Style/New Style の日付の違いと1752年に起きたことを調べることになった。Calendar (New Style) Act 1750 によると、18世紀まで英国の法律上の一年は、数世紀にわたって3月25日、つまり Lady Day に始まっていた
そのため、たとえば1707年3月24日の翌日は1708年3月25日で、1708年12月31日の翌日はまだ1708年1月1日であり、1709年はほぼ3か月先だった。変わって本当によかった
他の国にも、このような昔の遺産パッチがたくさん残っているのか気になる
しかし Carroll 方式は1月1日を元日と仮定しているため、正解である「Friday」に到達できない。興味深いことに、Carroll 方式を再出版した人たちはこの誤りを指摘しておらず、リンク先の記事にも同じ欠陥がある
calユーティリティには、1752年9月を認識する特別処理がある: https://github.com/util-linux/util-linux/blob/9f15d2de8117732845b2e891a2d24d987ee4e3ed/misc-utils/cal.c#L1079cal 1752を実行してみると、9月のカレンダーで水曜日の2日と木曜日の14日の間の日付が抜けている議論はあるが、グレゴリオ暦への移行がエイプリルフールの起源だという説明もある: https://en.wikipedia.org/wiki/April_Fools%27_Day, https://en.wikipedia.org/wiki/Gregorian_calendar
記事の月項目の計算法を追うのが難しい。記事では、母音で始まるか終わる月なら、その月の年内での順番を10から引き、そこにその月の日数を足すと次の月の項目になる、と説明している。
ところが1月の前の月である12月は母音で始まりも終わりもしないので、10から引かずに
12+31 ≡ 1になるはずなのに、記事では0だとしている。2月も January が母音で終わるので10-1+31 ≡ 4になるが、記事では3で、3月も February を基準に計算すると合わない。4月と5月は合うが、6月はまた合わないので、自分が何を誤解しているのか分からない。
(10-順番)+日数 mod 7という理屈は、前の月を基準にすると May、July、September、November のような隔月にしか合わず、母音ルールはこの計算をどの月に適用するかを覚えるための記憶法に近いように見える。残りの月は前月のitem+days mod 7を使うようだが、その解釈が記事のどこから導かれるのかは不明だ。1月は前月がないので、すべて0と見なし、結果も0にする。目的の月まで1月から毎回計算する必要はなく、始まりか終わりが母音の月は、その月の項目番号が
10-月番号だという近道を使える。このときyは母音とは見なさない。あるいは、単に暗記したほうがもっと楽かもしれない。Carroll のアルゴリズムは時とともに発展してきた。First Sunday Doomsday Algorithm(https://firstsundaydoomsday.blogspot.com/2009/12/quick-start-guide.html) は2023年までに公開された改良を含み、年コードを計算する Fong & Walters の「odd+11」ルールも入っている: https://arxiv.org/abs/1010.0765
これをもっと直感的に計算する方法だと思ってまとめておいた記事がある: https://gcanyon.wordpress.com/2013/04/09/a-better-way-to-calculate-the-day-of-the-week/
Art Benjamin が TED 講演でこれをやる場面は本当に興味深い。よく見ると、手の動きで途中計算を追跡しているのが分かる。
分かってしまえば当然に見えるが、とても賢いやり方だ。https://www.ted.com/talks/arthur_benjamin_a_performance_of_mathemagic の7:47から始まる。
Lewis Carroll 方式で今日、つまり2024年5月24日を計算するとこうなる。世紀項目は20世紀なので
20/4=5、余り0、3-0=3、3×2=6。年項目は
24/12=2、余り0、その中の4の個数が0なので2+0+0=2。月項目は記事では May=1、日項目は24。すべて足すと6+2+1+24=33、33 mod 7 = 5なので金曜日になる。表記法は重要ではないと言う人たちには、より良い新しい表記法を手に入れる前の数学は全部こんな姿だったと言いたい。
数学では表記法以外に重要なものはほとんどないとまで言えるし、コンピュータサイエンスも同じだ。変数が明示的なときに Lisp 系言語が明白な選択肢になる理由もここにある。
1600年代初めには “The white king commands his owne knight into the third house before his owne bishop.” で、1700年代半ばには
K. knight to His Bishop's 3d.、1800年代初めにはK.Kt. to B.third sq.、1890年ごろにはKKt-B3、1900年代半ばにはN-KB3、今ではNf3、または言語別の駒名を避けるなら♘f3になる: https://www.knightschessclub.org/the_history_of_notation.html20秒以内にできたなら、すごいと呼ぶに値する。本人は自分を速い計算家とは考えていなかった。
Python で曜日計算スクリプトを書いて
2024-05-24を入れると Friday が出る。世紀項目、年項目、月項目配列、日項目を足し、1〜2月のうるう年補正を適用する方式だ。1752年9月14日以前は別の世紀項目を使うように処理した。
こうして消えた日付は世界中で一斉に適用されたわけではなく、国や記録者の宗教によって適用時期が異なったため、歴史記録では今でも悩みの種になっている。