advent-of-code-2024/src/solutions/day_02.rs
2024-12-08 14:46:37 +01:00

83 lines
1.9 KiB
Rust

use itertools::Itertools;
use crate::common::{Answer, Solution};
pub struct Day02;
impl Solution for Day02 {
fn name(&self) -> &'static str {
"Red-Nosed Reports"
}
fn part_a(&self, input: &str) -> Answer {
input
.lines()
.filter(|l| {
let nums = l.split_whitespace().map(|n| n.parse::<i32>().unwrap());
is_valid(&nums)
})
.count()
.into()
}
fn part_b(&self, input: &str) -> Answer {
input
.lines()
.filter(|l| {
let nums = l.split_whitespace().map(|n| n.parse::<i32>().unwrap());
let valid = is_valid(&nums);
if !valid {
let len = nums.clone().count();
for skip_i in 0..len {
let new_nums = nums
.clone()
.enumerate()
.filter_map(|(i, n)| (skip_i != i).then_some(n));
if is_valid(&new_nums) {
return true;
}
}
}
valid
})
.count()
.into()
}
}
fn is_valid<T: Iterator<Item = i32> + Clone>(nums: &T) -> bool {
let diffs = nums.clone().tuple_windows().map(|(a, b)| a - b);
diffs.clone().all(|d| (-3..=-1).contains(&d)) || diffs.clone().all(|d| (1..=3).contains(&d))
}
#[cfg(test)]
mod test {
use super::Day02;
use crate::common::Solution;
use indoc::indoc;
const INPUT: &str = indoc! {"
7 6 4 2 1
1 2 7 8 9
9 7 6 2 1
1 3 2 4 5
8 6 4 4 1
1 3 6 7 9
"};
#[test]
fn part_a() {
assert_eq!(Day02.part_a(INPUT), 2.into());
}
#[test]
fn part_b() {
assert_eq!(Day02.part_b(INPUT), 4.into());
}
}