diff --git a/src/bin/problem_19.rs b/src/bin/problem_19.rs new file mode 100644 index 0000000..f894256 --- /dev/null +++ b/src/bin/problem_19.rs @@ -0,0 +1,81 @@ +use std::cmp::PartialEq; + +fn main() { + let mut sum_sundays = 0; + let mut first_day = Day::Monday; + for month in 0..12 { + let last_day = get_last_day(1900, month, first_day); + first_day = last_day.next(); + } + for year in 1901..2001 { + for month in 0..12 { + let last_day = get_last_day(year, month, first_day); + first_day = last_day.next(); + if first_day == Day::Sunday { + sum_sundays += 1; + } + } + } + println!("{sum_sundays}"); +} + +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +enum Day { + Monday, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday, + Sunday, +} + +impl Day { + fn next(self) -> Day { + match self { + Day::Monday => Day::Tuesday, + Day::Tuesday => Day::Wednesday, + Day::Wednesday => Day::Thursday, + Day::Thursday => Day::Friday, + Day::Friday => Day::Saturday, + Day::Saturday => Day::Sunday, + Day::Sunday => Day::Monday, + } + } + + fn day_num_in_week(self) -> usize { + match self { + Day::Monday => 0, + Day::Tuesday => 1, + Day::Wednesday => 2, + Day::Thursday => 3, + Day::Friday => 4, + Day::Saturday => 5, + Day::Sunday => 6, + } + } + + fn from_day_num(num: usize) -> Day { + match num { + 0 => Day::Monday, + 1 => Day::Tuesday, + 2 => Day::Wednesday, + 3 => Day::Thursday, + 4 => Day::Friday, + 5 => Day::Saturday, + 6 => Day::Sunday, + _ => panic!("day_num cannot be higher than 6 (counting days in week from 0)"), + } + } +} + +fn is_leap_year(year: usize) -> bool { + year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) +} + +fn get_last_day(year: usize, month: usize, first_day: Day) -> Day { + let days_per_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + let day_num = first_day.day_num_in_week(); + let days_in_month = if month == 1 && is_leap_year(year) { 29 } else { days_per_month[month] } + day_num; + Day::from_day_num((days_in_month - 1) % 7) +} \ No newline at end of file