year2024/
day02.rs

1use utils::array::ArrayVec;
2use utils::prelude::*;
3
4/// Checking sequences of numbers.
5#[derive(Clone, Debug)]
6pub struct Day02 {
7    reports: Vec<ArrayVec<u32, 8>>,
8}
9
10impl Day02 {
11    pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
12        Ok(Self {
13            reports: parser::u32().repeat_arrayvec(b' ', 1).parse_lines(input)?,
14        })
15    }
16
17    #[must_use]
18    pub fn part1(&self) -> usize {
19        self.reports
20            .iter()
21            .filter(|&r| Self::is_safe(r.iter().copied()))
22            .count()
23    }
24
25    #[must_use]
26    pub fn part2(&self) -> usize {
27        self.reports
28            .iter()
29            .filter(|&r| {
30                if Self::is_safe(r.iter().copied()) {
31                    return true;
32                }
33
34                (0..r.len())
35                    .any(|i| Self::is_safe(r.iter().take(i).chain(r.iter().skip(i + 1)).copied()))
36            })
37            .count()
38    }
39
40    #[inline]
41    fn is_safe(iter: impl Iterator<Item = u32> + Clone) -> bool {
42        let mut w = iter.clone().zip(iter.skip(1));
43
44        w.clone().all(|(a, b)| (1..=3).contains(&a.wrapping_sub(b)))
45            || w.all(|(a, b)| (1..=3).contains(&b.wrapping_sub(a)))
46    }
47}
48
49examples!(Day02 -> (usize, usize) [
50    {input: "7 6 4 2 1", part1: 1, part2: 1},
51    {input: "1 2 7 8 9", part1: 0, part2: 0},
52    {input: "9 7 6 2 1", part1: 0, part2: 0},
53    {input: "1 3 2 4 5", part1: 0, part2: 1},
54    {input: "8 6 4 4 1", part1: 0, part2: 1},
55    {input: "1 3 6 7 9", part1: 1, part2: 1},
56]);