1use crate::util::parse::*;
6
7type Input = (u32, u32);
8
9pub fn parse(input: &str) -> Input {
10 let memory = input.as_bytes();
11 let mut index = 0;
12 let mut enabled = true;
13 let mut part_one = 0;
14 let mut part_two = 0;
15
16 while index < memory.len() {
17 if !matches!(memory[index], b'm' | b'd') {
19 index += 1;
20 continue;
21 }
22
23 if memory[index..].starts_with(b"mul(") {
25 index += 4;
26 } else if memory[index..].starts_with(b"do()") {
27 index += 4;
28 enabled = true;
29 continue;
30 } else if memory[index..].starts_with(b"don't()") {
31 index += 7;
32 enabled = false;
33 continue;
34 } else {
35 index += 1;
36 continue;
37 }
38
39 let Some(first) = parse_number(memory, &mut index, b',') else { continue };
41 index += 1;
42
43 let Some(second) = parse_number(memory, &mut index, b')') else { continue };
45 index += 1;
46
47 let product = first * second;
49 part_one += product;
50 part_two += product * u32::from(enabled);
51 }
52
53 (part_one, part_two)
54}
55
56pub fn part1(input: &Input) -> u32 {
57 input.0
58}
59
60pub fn part2(input: &Input) -> u32 {
61 input.1
62}
63
64fn parse_number(memory: &[u8], index: &mut usize, delimiter: u8) -> Option<u32> {
65 let mut number = 0;
66
67 while memory[*index].is_ascii_digit() {
68 number = 10 * number + memory[*index].to_decimal::<u32>();
69 *index += 1;
70 }
71
72 (memory[*index] == delimiter).then_some(number)
73}