From 7bf66496af3b31dee24310a8360641791f22938d Mon Sep 17 00:00:00 2001 From: Aaron Manning Date: Fri, 6 Dec 2024 18:18:34 +1100 Subject: [PATCH] day 2 --- day-02/Cargo.lock | 7 +++++ day-02/Cargo.toml | 6 +++++ day-02/src/main.rs | 65 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 day-02/Cargo.lock create mode 100644 day-02/Cargo.toml create mode 100644 day-02/src/main.rs diff --git a/day-02/Cargo.lock b/day-02/Cargo.lock new file mode 100644 index 0000000..5de1616 --- /dev/null +++ b/day-02/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "day-02" +version = "0.1.0" diff --git a/day-02/Cargo.toml b/day-02/Cargo.toml new file mode 100644 index 0000000..b450e6a --- /dev/null +++ b/day-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day-02" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/day-02/src/main.rs b/day-02/src/main.rs new file mode 100644 index 0000000..09e1f44 --- /dev/null +++ b/day-02/src/main.rs @@ -0,0 +1,65 @@ +const INPUT: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/input.txt")); + +fn main() { + let mut safe = 0; + for line in INPUT.lines() { + let report = line + .split_whitespace() + .filter_map(|num| { + str::parse::(num).ok() + }); + + safe += u16::from(is_safe(report)); + } + + println!("Part 1: {}", safe); + + let mut still_safe = 0; + for line in INPUT.lines() { + let report = line + .split_whitespace() + .filter_map(|num| { + str::parse::(num).ok() + }); + + still_safe += u16::from(is_still_safe(report)); + } + + println!("Part 2: {}", still_safe); +} + +fn is_safe(mut report: impl Iterator) -> bool { + let mut ascending = true; + let mut descending = true; + let mut correct_gaps = true; + let Some(mut prev) = report.next() else { + return true; + }; + while let Some(level) = report.next() { + ascending &= prev <= level; + descending &= prev >= level; + correct_gaps &= matches!(prev.abs_diff(level), 1..=3); + + prev = level; + } + + (ascending || descending) && correct_gaps +} + +fn is_still_safe(report: impl Iterator) -> bool { + let report = report.collect::>(); + let mut is_still_safe = false; + for removal in 0..report.len() { + let altered_report = report.iter().copied().enumerate().filter_map(|(idx, level)| { + if idx == removal { + None + } else { + Some(level) + } + }); + + is_still_safe |= is_safe(altered_report); + }; + + is_still_safe +}