generated from fspoettel/advent-of-code-rust
-
Notifications
You must be signed in to change notification settings - Fork 0
/
03.rs
69 lines (61 loc) · 1.76 KB
/
03.rs
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
69
advent_of_code::solution!(3);
use regex::Regex;
enum Instruction {
Mul(u32, u32),
Do,
Dont,
}
fn parse_instructions(input: &str) -> Vec<Instruction> {
let re = Regex::new(r"mul\((\d+),(\d+)\)|do\(\)|don't\(\)").unwrap();
re.captures_iter(input)
.map(|capture| match &capture[0] {
"do()" => Instruction::Do,
"don't()" => Instruction::Dont,
_ => {
let a = capture[1].parse::<u32>().unwrap();
let b = capture[2].parse::<u32>().unwrap();
Instruction::Mul(a, b)
}
})
.collect()
}
pub fn part_one(input: &str) -> Option<u32> {
Some(parse_instructions(input).iter().fold(0, |acc, x| match x {
Instruction::Mul(a, b) => acc + a * b,
_ => acc,
}))
}
pub fn part_two(input: &str) -> Option<u32> {
Some(
parse_instructions(input)
.iter()
.fold((0, true), |acc: (u32, bool), x| match x {
Instruction::Do => (acc.0, true),
Instruction::Dont => (acc.0, false),
Instruction::Mul(a, b) => {
if acc.1 {
(acc.0 + a * b, acc.1)
} else {
(acc.0, acc.1)
}
}
})
.0,
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part_one() {
let result =
part_one("xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))");
assert_eq!(result, Some(161));
}
#[test]
fn test_part_two() {
let result =
part_two("xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))");
assert_eq!(result, Some(48));
}
}