year2018/
day02.rs

1use std::collections::HashSet;
2use utils::array::ArrayVec;
3use utils::prelude::*;
4
5/// Finding near-match IDs.
6#[derive(Clone, Debug)]
7pub struct Day02 {
8    ids: Vec<ArrayVec<u8, 32>>,
9}
10
11impl Day02 {
12    pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
13        Ok(Self {
14            ids: parser::byte_range(b'a'..=b'z')
15                .repeat_arrayvec(parser::noop(), 1)
16                .parse_lines(input)?,
17        })
18    }
19
20    #[must_use]
21    #[expect(clippy::manual_contains, reason = ".iter().any() is faster here")]
22    pub fn part1(&self) -> u32 {
23        let mut twos = 0;
24        let mut threes = 0;
25        for id in &self.ids {
26            let mut freq = [0u8; 26];
27            for &i in id {
28                freq[(i - b'a') as usize] += 1;
29            }
30            twos += u32::from(freq.iter().any(|&x| x == 2));
31            threes += u32::from(freq.iter().any(|&x| x == 3));
32        }
33        twos * threes
34    }
35
36    #[must_use]
37    pub fn part2(&self) -> String {
38        let mut seen = HashSet::with_capacity(self.ids.len());
39        for column in 0..self.ids[0].capacity() {
40            for mut id in self.ids.iter().map(|id| id.clone().into_array()) {
41                id[column] = 0;
42                if !seen.insert(id) {
43                    return id.iter().filter(|&&x| x != 0).map(|&x| x as char).collect();
44                }
45            }
46            seen.clear();
47        }
48        panic!("no solution found")
49    }
50}
51
52examples!(Day02 -> (u32, &'static str) [
53    {input: "abcdef\nbababc\nabbcde\nabcccd\naabcdd\nabcdee\nababab", part1: 12},
54    {input: "abcde\nfghij\nklmno\npqrst\nfguij\naxcye\nwvxyz", part2: "fgij"},
55]);