1use utils::array::ArrayVec;
2use utils::prelude::*;
3
4#[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]);