Problem 19 - 曜日計算
だんだん難しくなってきた。
次の情報が与えられている。
* 1900年1月1日は月曜日である。
* 9月、4月、6月、11月は30日まであり、2月を除く他の月は31日まである。
* 2月は28日まであるが、うるう年のときは29日である。
* うるう年は西暦が4で割り切れる年に起こる。しかし、西暦が400で割り切れず100で割り切れる年はうるう年でない。20世紀(1901年1月1日から2000年12月31日)で月の初めの日曜日の数を数えよ。
曜日計算か。はじめてかも。
とりあえず曜日計算の公式を探そう。googleにツェラーの公式とか入れると、ガリガリ出てくる。
うほ。良い解説。
閏年の計算を最後に回すために、14月とするのか。なるほど!!
ツェラーの公式まんまだと扱いにくいので、year,mon,dayで出せるようにしてみた。
(define (problem19 n) (define (w year mon day) (define (z year m d) (let ((h (quotient year 100)) (y (modulo year 100))) (modulo (+ (quotient h 4) (quotient y 4) y (- (* 2 h)) (quotient (* (+ m 1) 13) 5) d) 7))) (if (<= mon 2) (z (- year 1) (+ mon 12) day) (z year mon day))) (define (iter y m e) (cond ((> y e) 0) ((> m 12) (iter (+ y 1) 1 e)) (else (+ (if (= (w y m 1) 1) 1 0) (iter y (+ m 1) e))))) (iter (- (* n 100) 99) 1 (* n 100))) (problem19 20) ; 171
余りって不思議な世界。