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
49 let mut seen = FastSet::with_capacity(input.len());
50 let mut buffer = [0; 32];
51
52 for column in 0..width {
54 for &id in input {
55 buffer[0..width].copy_from_slice(id);
56 buffer[column] = b'*';
57
58 if !seen.insert(buffer) {
59 return buffer
61 .iter()
62 .filter(|&&b| b.is_ascii_lowercase())
63 .map(|&b| b as char)
64 .collect();
65 }
66 }
67
68 seen.clear();
69 }
70
71 unreachable!()
72}