ZODIACの黙示録

なにもしないことをする

ワンライナーHaskellでグレゴリオオンリーのツェラーの公式を書いた

はじめに

こんにちはゾディアックです。
この記事はアドベントカレンダー
PMOB Advent Calendar 2018 - Adventar
13日目の記事です。
尿意を催してきたので、急いで書かせて貰います。
f:id:zodi_G12:20181213200049j:plain

ツェラーの公式

西暦と月と日を引数とし、曜日を返す関数です。
ツェラーの公式 - Wikipedia
詳しくはググってください。今回はグレゴリオ歴オンリーです。
故に恒常的に
 \Gamma = 5C+ \lfloor \frac{C}{4} \rfloor
とする。
f:id:zodi_G12:20181213200135j:plain

パパっとやって、終りっ

以下がコード(関数)です。ghciとかでやってください。
y:year, m:month, d:dayです。
1,2月が前年分の13,14月に変貌させないといけない使用なのですが、
if文や三項演算子みたいなものを使用して実装すると、
我が感覚的にキモいと思いました。
そこでmonthの、
 1,2,3,4,5,6,7,8,9,10,11,12

 13,14,3,4,5,6,7,8,9,10,11,12
に対応させる関数を片手間で考えました。
yearも対応して1,2月のときには前年に対応させる必要があります。
考えたのがこれです。
 m = (m+12) - 12(\lfloor \frac{m+12}{15} \rfloor)
以下が完全コード(純粋関数)です。今度最適化します。

greZel y m d = ["MON","TUE","WED","THU","FRI","SAT","SUN"]!!((d+(26*((m+12-12*((m+12)`div`15)+1))`div`10)+(y+((m+12)`div`15)-1)`mod`100+((y+((m+12)`div`15)-1)`mod`100)`div`4+5*((y+((m+12)`div`15)-1)`div`100)+((y+((m+12)`div`15)-1)`div`100)`div`4+5)`mod`7)

f:id:zodi_G12:20181213201608j:plain

えぐいので書き換えると

greZel y m d = ["MON","TUE","WED","THU","FRI","SAT","SUN"]!!
          ((d
          +(26*((m+12-12*((m+12)`div`15)+1))`div`10)
          +(y+((m+12)`div`15)-1)`mod`100
          +((y+((m+12)`div`15)-1)`mod`100)`div`4
          +5*((y+((m+12)`div`15)-1)`div`100)
          +((y+((m+12)`div`15)-1)`div`100)`div`4
          +5)
          `mod`7)

もっというと

greZel y m d = ["MON","TUE","WED","THU","FRI","SAT","SUN"]!!
          ((d
          +(26*(m1+1))`div`10
          +y2
          +y2`div`4
          +ga
          +5)`mod`7)
            where 
                 m1 = m+12 - 12*((m+12) `div` 15)           
                 y1 = y + ((m+12) `div` 15) - 1
                 y2 = y1 `mod` 100
                 c  = y1 `div` 100
                 ga = 5*c + c `div` 4

f:id:zodi_G12:20181213210232j:plain

最後に

久々にコード書きました。
ワンライナーとか馬鹿なので絶対にやらない方がいいです。
赤ワイン昨日買ったばっかなのにもう無いのはおかしいと思う。
f:id:zodi_G12:20181213192055j:plain