1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
use std::io::{self, Read};
#[derive(Debug)]
enum Instruction {
Do,
Dont,
Mul(u64, u64),
}
impl From<&Instruction> for u64 {
fn from(val: &Instruction) -> Self {
match val {
Instruction::Mul(x, y) => x * y,
_ => 0,
}
}
}
fn main() -> io::Result<()> {
let mut program = String::new();
io::stdin().read_to_string(&mut program)?;
let instrs = (0..program.len())
.filter_map(|idx| {
let next = &program[idx..];
if next.starts_with("do()") {
Some(Instruction::Do)
} else if next.starts_with("don't()") {
Some(Instruction::Dont)
} else if next.starts_with("mul(") {
let mut first = 0;
let mut curr = 0;
for ch in next.bytes().skip(4) {
match (ch, curr) {
((b'0'..=b'9'), _) => curr = curr * 10 + (ch - b'0') as u64,
(_, 0) => return None,
(b',', _) => {
first = curr;
curr = 0;
}
(b')', _) => {
return Some(Instruction::Mul(first, curr));
}
_ => return None,
};
}
None
} else {
None
}
})
.collect::<Vec<_>>();
let silver: u64 = instrs.iter().map(u64::from).sum();
let (gold, _) = instrs
.iter()
.fold((0 as u64, true), |(acc, on), instr| match (instr, on) {
(Instruction::Do, _) => (acc, true),
(Instruction::Dont, _) => (acc, false),
(Instruction::Mul(_, _), true) => (acc + u64::from(instr), true),
_ => (acc, on),
});
println!("silver: {silver}");
println!("gold: {gold}");
return Ok(());
}
|