1use utils::prelude::*;
2
3#[derive(Clone, Debug)]
5pub struct Day03 {
6 part1: u32,
7 part2: u32,
8}
9
10enum Instruction {
11 Mul(u32, u32),
12 Do,
13 Dont,
14}
15
16impl Day03 {
17 pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
18 let matches = parser::parse_tree!(
19 ("mul(", a @ parser::u32(), ",", b @ parser::u32(), ")") => Instruction::Mul(a, b),
20 ("don't()") => Instruction::Dont,
21 ("do()") => Instruction::Do,
22 )
23 .matches_iterator(input);
24
25 let (mut part1, mut part2) = (0, 0);
26 let mut enabled = true;
27 for instruction in matches {
28 match instruction {
29 Instruction::Mul(a, b) => {
30 part1 += a * b;
31 part2 += if enabled { a * b } else { 0 };
32 }
33 Instruction::Do => enabled = true,
34 Instruction::Dont => enabled = false,
35 }
36 }
37
38 Ok(Self { part1, part2 })
39 }
40
41 #[must_use]
42 pub fn part1(&self) -> u32 {
43 self.part1
44 }
45
46 #[must_use]
47 pub fn part2(&self) -> u32 {
48 self.part2
49 }
50}
51
52examples!(Day03 -> (u32, u32) [
53 {input: "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))", part1: 161},
54 {input: "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))", part2: 48},
55]);