1use utils::bit::BitIterator;
2use utils::prelude::*;
3
4#[derive(Clone, Debug)]
6pub struct Day10 {
7 part1: u64,
8 part2: u64,
9}
10
11const MAX: usize = 255;
12
13impl Day10 {
14 pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
15 let (mut count, mut adapters) = (0, [0u64; MAX.div_ceil(64)]);
16 for entry in parser::number_range(1..=MAX)
17 .with_eol()
18 .parse_iterator(input)
19 {
20 let n = entry?;
21 adapters[n / 64] |= 1 << (n % 64);
22 count += 1;
23 }
24
25 if count == 0 {
26 return Err(InputError::new(input, 0, "expected at least one adapter"));
27 }
28 if count != adapters.iter().map(|w| w.count_ones()).sum::<u32>() {
29 return Err(InputError::new(input, 0, "duplicate adapter"));
30 }
31
32 let (mut ones, mut threes) = (0u64, 1u64);
33
34 let (mut previous, mut ways) = (0, [1u64, 0, 0]);
36
37 for (i, word) in adapters.into_iter().enumerate() {
38 for (bit, _) in BitIterator::ones(word) {
39 let jolts = i * 64 + bit as usize;
40
41 match jolts - previous {
42 1 => {
43 ones += 1;
44 ways = [ways[0] + ways[1] + ways[2], ways[0], ways[1]];
45 }
46 2 => ways = [ways[0] + ways[1], 0, ways[0]],
47 3 => {
48 threes += 1;
49 ways = [ways[0], 0, 0];
50 }
51 _ => return Err(InputError::new(input, 0, "expected a valid adapter chain")),
52 }
53 previous = jolts;
54 }
55 }
56
57 Ok(Self {
58 part1: ones * threes,
59 part2: ways[0],
60 })
61 }
62
63 #[must_use]
64 pub fn part1(&self) -> u64 {
65 self.part1
66 }
67
68 #[must_use]
69 pub fn part2(&self) -> u64 {
70 self.part2
71 }
72}
73
74examples!(Day10 -> (u64, u64) [
75 {file: "day10_example0.txt", part1: 35, part2: 8},
76 {file: "day10_example1.txt", part1: 220, part2: 19208},
77]);