1use utils::prelude::*;
2
3#[derive(Clone, Debug)]
5pub struct Day06 {
6 part1: u32,
7 part2: u32,
8}
9
10const ALL_ANSWERS: u32 = (1 << 26) - 1;
11const ANSWER_BITS: [Option<u32>; 256] = {
12 let mut bits = [None; 256];
13 let mut i = 0u8;
14 while i < 26 {
15 bits[(b'a' + i) as usize] = Some(1 << i);
16 i += 1;
17 }
18 bits
19};
20
21impl Day06 {
22 pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
23 let bytes = input.as_bytes();
24 let (mut part1, mut part2) = (0, 0);
25 let (mut any, mut every, mut person) = (0u32, ALL_ANSWERS, 0u32);
26
27 for (index, &b) in bytes.iter().enumerate() {
28 if let Some(answer) = ANSWER_BITS[b as usize] {
29 person |= answer;
30 } else if b == b'\n' {
31 if person != 0 {
32 any |= person;
33 every &= person;
34 person = 0;
35 } else {
36 if any == 0 {
37 return Err(InputError::new(input, index, "expected lowercase letter"));
38 }
39 part1 += any.count_ones();
40 part2 += every.count_ones();
41 (any, every) = (0, ALL_ANSWERS);
42 }
43 } else if !(b == b'\r' && bytes.get(index + 1) == Some(&b'\n')) {
44 return Err(InputError::new(input, index, "expected lowercase letter"));
45 }
46 }
47
48 if person != 0 {
49 any |= person;
50 every &= person;
51 }
52
53 if any == 0 {
54 return Err(InputError::new(
55 input,
56 input.len(),
57 "expected lowercase letter",
58 ));
59 }
60 part1 += any.count_ones();
61 part2 += every.count_ones();
62
63 Ok(Self { part1, part2 })
64 }
65
66 #[must_use]
67 pub fn part1(&self) -> u32 {
68 self.part1
69 }
70
71 #[must_use]
72 pub fn part2(&self) -> u32 {
73 self.part2
74 }
75}
76
77examples!(Day06 -> (u32, u32) [
78 {input: "abcx\nabcy\nabcz", part1: 6},
79 {input: "abc\n\na\nb\nc\n\nab\nac\n\na\na\na\na\n\nb", part1: 11, part2: 6},
80]);