1use crate::util::hash::*;
3
4pub fn parse(input: &str) -> Vec<&[u8]> {
5 input.lines().map(str::as_bytes).collect()
6}
7
8pub fn part1(input: &[&[u8]]) -> u32 {
9 let mut total_twos = 0;
10 let mut total_threes = 0;
11
12 for &id in input {
13 let mut freq = [0; 26];
15 let mut twos = 0;
16 let mut threes = 0;
17
18 for &b in id {
19 let index = (b - b'a') as usize;
20 let current = freq[index];
21
22 match current {
23 0 => (),
24 1 => twos += 1,
25 2 => {
26 twos -= 1;
27 threes += 1;
28 }
29 _ => threes -= 1,
30 }
31
32 freq[index] += 1;
33 }
34
35 if twos > 0 {
36 total_twos += 1;
37 }
38 if threes > 0 {
39 total_threes += 1;
40 }
41 }
42
43 total_twos * total_threes
44}
45
46pub fn part2(input: &[&[u8]]) -> String {
47 let width = input[0].len();
48 let mut seen = FastSet::with_capacity(input.len());
49
50 for column in 0..width {
53 for &id in input {
54 let prefix = &id[..column];
55 let suffix = &id[column + 1..];
56
57 if !seen.insert([prefix, suffix]) {
58 return prefix.iter().chain(suffix).copied().map(char::from).collect();
60 }
61 }
62
63 seen.clear();
64 }
65
66 unreachable!()
67}