42 lines
1.2 KiB
Haskell
42 lines
1.2 KiB
Haskell
|
data Weekday = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday
|
||
|
deriving (Show, Eq, Ord, Enum)
|
||
|
|
||
|
data Month = January | February | March | April | May | June | July | August | September | October | November | December
|
||
|
deriving (Show, Eq, Ord, Enum)
|
||
|
|
||
|
type Day = Int
|
||
|
type Year = Int
|
||
|
|
||
|
data Date = Date Year Month Day Weekday
|
||
|
deriving (Show, Eq, Ord)
|
||
|
|
||
|
nextWeekday :: Weekday -> Weekday
|
||
|
nextWeekday Sunday = Monday
|
||
|
nextWeekday d = succ d
|
||
|
|
||
|
nextMonth :: Month -> Month
|
||
|
nextMonth December = January
|
||
|
nextMonth m = succ m
|
||
|
|
||
|
getDays :: Month -> Year -> Int
|
||
|
getDays m y
|
||
|
| elem m [September, April, June, November] = 30
|
||
|
| m == February = if rem y 4 == 0 && if rem y 100 == 0 && rem y 400 /= 0 then False else True
|
||
|
then 29 else 28
|
||
|
| otherwise = 31
|
||
|
|
||
|
nextDate :: Date -> Date
|
||
|
nextDate (Date y m d wd)
|
||
|
| d < getDays m y = Date y m (d+1) (nextWeekday wd)
|
||
|
| m == December = Date (y+1) January 1 (nextWeekday wd)
|
||
|
| otherwise = Date y (nextMonth m) 1 (nextWeekday wd)
|
||
|
|
||
|
|
||
|
daysTwentieth :: [Date]
|
||
|
daysTwentieth = takeWhile (\(Date y _ _ _) -> y /=2001) (dates start)
|
||
|
where
|
||
|
dates d = d:dates (nextDate d)
|
||
|
start = Date 1901 January 1 Tuesday
|
||
|
|
||
|
e019 = length . filter (\(Date y m d wd) -> d == 1 && wd == Sunday) $ daysTwentieth
|