Problem 19 - 曜日計算

だんだん難しくなってきた。

Problem 19 - PukiWiki

次の情報が与えられている。

* 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

余りって不思議な世界。