Files
project-euler/19_saturdays.fs
T
2025-08-03 20:16:55 -07:00

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