63 lines
1.5 KiB
FSharp
63 lines
1.5 KiB
FSharp
module _19
|
|
|
|
open common
|
|
|
|
//1 Jan 1900 was a Monday.
|
|
//Thirty days has September,
|
|
//April, June and November.
|
|
//All the rest have thirty-one,
|
|
//Saving February alone,
|
|
//Which has twenty-eight, rain or shine.
|
|
//And on leap years, twenty-nine.
|
|
//A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.
|
|
|
|
type day =
|
|
Sunday | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday
|
|
|
|
let dayNum d =
|
|
match d with
|
|
| Sunday -> 0
|
|
| Monday -> 1
|
|
| Tuesday -> 2
|
|
| Wednesday -> 3
|
|
| Thursday -> 4
|
|
| Friday -> 5
|
|
| Saturday -> 6
|
|
|
|
let numDay n =
|
|
match n with
|
|
| 0 -> Sunday
|
|
| 1 -> Monday
|
|
| 2 -> Tuesday
|
|
| 3 -> Wednesday
|
|
| 4 -> Thursday
|
|
| 5 -> Friday
|
|
| 6 -> Saturday
|
|
| _ -> raise(System.ArgumentException("No!"))
|
|
|
|
type date =
|
|
{ Year : int;
|
|
Month : int }
|
|
|
|
let isLeapYear y =
|
|
y % 4 = 0 && (y % 100 <> 0 || y % 400 = 0)
|
|
|
|
let getDaysInMonth d =
|
|
let thirtyMonths = [|9;4;6;11|];
|
|
match d with
|
|
| date when date.Month = 2 && isLeapYear date.Year -> 29
|
|
| date when date.Month = 2 -> 28
|
|
| date when Array.exists ((=) date.Month) thirtyMonths -> 30
|
|
| _ -> 31
|
|
|
|
let getNextFirstDay d daysInMonth =
|
|
(daysInMonth + (dayNum d)) % 7 |> numDay
|
|
|
|
let firstSaturdays =
|
|
//getNextFirstDay Thursday 30
|
|
crossMapList [1900..1999] [1..12]
|
|
|> Seq.map (fun (y, m) -> { Year = y; Month = m })
|
|
|> Seq.scan (fun (day:day) ym -> getNextFirstDay day (getDaysInMonth ym)) Monday
|
|
|> Seq.filter ((=) Sunday)
|
|
|> Seq.length
|