import Data.Monoid data Month = Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec deriving (Eq,Ord,Enum,Bounded,Show) data Day = Sun | Mon | Tue | Wed | Thu | Fri | Sat deriving (Eq,Ord,Enum,Bounded,Show) type Year = Int leapYear yr = yr `mod` 400 == 0 || (yr `mod` 4 == 0 && yr `mod` 100 /= 0) daysInMonth :: (Month, Year) -> Int daysInMonth (mn, yr) | mn `elem` [ Sep, Apr, Jun, Nov ] = 30 | mn == Feb = if leapYear yr then 29 else 28 | otherwise = 31 nextMonth (Dec, yr) = (Jan, yr + 1) nextMonth (mn, yr) = (succ mn, yr) compareMonths (m1,y1) (m2,y2) = compare y1 y2 <> compare m1 m2 addDays d n = toEnum $ (fromEnum d + n) `mod` 7 startDay = ((Jan, 1900), Mon) : [ (nextMonth m, addDays d n) | (m, d) <- startDay, let n = daysInMonth m ] main = print $ length $ filter ((== Sun) . snd) $ takeWhile (\(m,_) -> m `compareMonths` (Dec, 2000) /= GT) $ dropWhile (\(m,_) -> m `compareMonths` (Jan, 1901) == LT) $ startDay