Problem 19

http://projecteuler.net/index.php?section=problems&id=19

1900-01-01は月曜日
4月、6月、9月、11月は30日
2月は、うるう年なら29日、そうでないなら28日
うるう年とは、4で割り切れかつ100で割れないものである。ただし400で割り切れるものはうるう年である。

1901-01-01〜2000-12-31までで月の最初の日が日曜日である月の数は?

nDay19000101 = 1

main = print $ length $ filter (== 0) $ drop 12 $ scanl f nDay19000101 $ init $ concatMap numberOfDay [1900..2000]
    where f lastMonth n = (lastMonth + n) `mod` 7

numberOfDay:: Int -> [Int]
numberOfDay year = [31, february, 31, 30,
                    31, 30, 31, 31,
                    30, 31, 30, 31]
    where february = if isLeapYear then 29 else 28
          isLeapYear = year `isDivisible` 4 &&
                       (not (year `isDivisible` 100) || year `isDivisible` 400)

isDivisible a b = (a `mod` b) == 0

もっとキレイにならんものか。