Euler problem 19.2

How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?

isLeap :: Int -> Bool
isLeap year
  = (mod year 4 == 0
     && mod year 100 /= 0)
  || mod year 400 == 0

daysInMonth :: Int -> Int -> Int
daysInMonth year month
  | month `elem` [1, 3, 5, 7, 8, 10, 12] = 31
  | month `elem` [4, 6, 9, 11] = 30
  | month == 2 = if isLeap year
                 then 29
                 else 28

nextMonth :: Int -> Int -> Int -> Int
nextMonth dayOfWeek y m 
  = (dayOfWeek + daysInMonth y m) `mod` 7

countSundays :: Int -> Int -> Int -> Int -> Int
countSundays startYear startMonth dayOfWeek sundays
  | y > 2000  = sundays
  | m > 12    = countSundays (y+1) 1 dayOfWeek sundays
  | otherwise = countSundays y (m+1) nextDayOfWeek sun
  where
    y = startYear
    m = startMonth
    nextDayOfWeek = nextMonth dayOfWeek y m 
    sun | dayOfWeek == 0 = sundays + 1
        | otherwise      = sundays

e19 :: Int
e19 = countSundays 1901 1 2 0
-- The third argument is dayOfWeek.
-- Its value is 2 here  
-- because 1 Jan 1901 was a Tuesday. 

λ> e19
171
λ> 

— Me@2024-02-10 12:00:39 PM

.

.

2024.02.11 Sunday (c) All rights reserved by ACHK