From 32419b72a863dcef15468f6ba40e0dbd8274a45b Mon Sep 17 00:00:00 2001 From: Jack Kinsey Date: Tue, 3 Dec 2024 02:01:58 -0500 Subject: [PATCH] Complete day 2 --- src/day02.rs | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 3 ++ 2 files changed, 122 insertions(+) create mode 100644 src/day02.rs diff --git a/src/day02.rs b/src/day02.rs new file mode 100644 index 0000000..39148fd --- /dev/null +++ b/src/day02.rs @@ -0,0 +1,119 @@ +fn input() -> &'static str { + include_str!("../input/day02.txt") +} + +fn parse(input: &str) -> Vec> { + input + .split_terminator('\n') + .map(|l| l.split_whitespace().map(|n| n.parse().unwrap()).collect()) + .collect() +} + +fn is_monotonic(d: &[i32]) -> bool { + let (inc, dec, _) = d + .iter() + .fold((0, 0, None as Option), |(inc, dec, k), n| match k { + Some(k) => { + if n - k > inc { + (n - k, dec, Some(*n)) + } else if n - k < dec { + (inc, n - k, Some(*n)) + } else { + (inc, dec, Some(*n)) + } + } + None => (inc, dec, Some(*n)), + }); + inc > 0 && dec == 0 || inc == 0 && dec < 0 +} + +fn safe_gaps(d: &[i32]) -> bool { + d.iter() + .zip(d.iter().skip(1)) + .map(|(l, &r)| l.abs_diff(r)) + .all(|t| (1..=3).contains(&t)) +} + +fn is_safe(d: &[i32]) -> bool { + is_monotonic(d) && safe_gaps(d) +} + +fn is_safe_dampened(d: &[i32]) -> bool { + is_safe(d) + || (0..d.len()) + .map(|i| d.iter().take(i).chain(d.iter().skip(i + 1))) + .map(|v| is_safe(&v.copied().collect::>())) + .any(|x| x) +} + +pub fn part1() { + let vecs = parse(input()); + let n = vecs.iter().map(|v| is_safe(v)).filter(|&x| x).count(); + println!("Day 2 Part 1: {}", n); +} + +pub fn part2() { + let vecs = parse(input()); + let n = vecs + .iter() + .map(|v| is_safe_dampened(v)) + .filter(|&x| x) + .count(); + println!("Day 2 Part 2: {}", n); +} + +#[cfg(test)] +mod test { + use super::*; + + const INPUT_STR: &str = concat!( + "7 6 4 2 1\n", + "1 2 7 8 9\n", + "9 7 6 2 1\n", + "1 3 2 4 5\n", + "8 6 4 4 1\n", + "1 3 6 7 9\n", + ); + + #[test] + fn test_parse() { + assert_eq!( + parse(INPUT_STR), + vec![ + vec![7, 6, 4, 2, 1], + vec![1, 2, 7, 8, 9], + vec![9, 7, 6, 2, 1], + vec![1, 3, 2, 4, 5], + vec![8, 6, 4, 4, 1], + vec![1, 3, 6, 7, 9], + ] + ) + } + + #[test] + fn test_monotonicity() { + let vecs = parse(INPUT_STR); + assert_eq!( + vecs.iter().map(|v| is_monotonic(v)).collect::>(), + vec![true, true, true, false, true, true] + ) + } + + #[test] + fn test_safe_gaps() { + let vecs = parse(INPUT_STR); + assert_eq!( + vecs.iter().map(|v| safe_gaps(v)).collect::>(), + vec![true, false, false, true, false, true] + ) + } + + #[test] + fn test_dampened_gaps() { + let vecs = parse(INPUT_STR); + assert_eq!( + vecs.iter().map(|v| is_safe_dampened(v)).collect::>(), + vec![true, false, false, true, true, true] + ) + } +} diff --git a/src/main.rs b/src/main.rs index d54a6f6..5b055ca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,9 @@ pub mod day01; +pub mod day02; fn main() { day01::part1(); day01::part2(); + day02::part1(); + day02::part2(); } -- 2.38.5