#[derive(PartialEq, Clone, Copy)] enum Direction { Up, Down, Unknown, } use Direction::*; fn is_safe(levels: &[u32]) -> bool { let mut direction = Unknown; for i in 0..levels.len() - 1 { let [x, y] = levels[i..=i + 1] else { unreachable!() }; let (diff, d) = if x > y { (x - y, Down) } else { (y - x, Up) }; if direction == Unknown { direction = d; } if diff == 0 || diff > 3 || direction != d { return false; } } return true; } pub fn p1(input: &str) -> String { let mut total = 0; for report in input.lines() { let levels: Vec = report .split_whitespace() .map(|l| l.parse().unwrap()) .collect(); if is_safe(&levels) { total += 1; } } total.to_string() } fn is_safe_with_dampener(levels: &[u32]) -> bool { for i in 0..levels.len() { let mut levels_without_i: Vec = levels.to_vec(); levels_without_i.remove(i); if is_safe(&levels_without_i) { return true; } } return false; } pub fn p2(input: &str) -> String { let mut total = 0; for report in input.lines() { let levels: Vec = report .split_whitespace() .map(|l| l.parse().unwrap()) .collect(); if is_safe(&levels) || is_safe_with_dampener(&levels) { total += 1; } } total.to_string() }