-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday03.rs
82 lines (73 loc) · 2.38 KB
/
day03.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
70
71
72
73
74
75
76
77
78
79
80
81
82
use aoc_lib::{answer::Answer, solution::Solution};
use regex::Regex;
pub struct Day3;
impl Solution for Day3 {
fn part_a(&self, input: &[String]) -> Answer {
let mut answer = 0;
for line in input {
let instructions = extract_instructions(line.as_str());
for inst in instructions {
if let Instruction::Mul(first, second) = inst {
answer += first * second;
}
}
}
answer.into()
}
fn part_b(&self, input: &[String]) -> Answer {
let mut answer = 0;
let mut enable = true;
for line in input {
let instructions = extract_instructions(line.as_str());
for inst in instructions {
match inst {
Instruction::Do => enable = true,
Instruction::Dont => enable = false,
Instruction::Mul(first, second) if enable => answer += first * second,
Instruction::Mul(_, _) => (),
}
}
}
answer.into()
}
}
#[derive(Copy, Clone, Debug)]
enum Instruction {
Mul(i32, i32),
Do,
Dont,
}
fn extract_instructions(s: &str) -> Vec<Instruction> {
let re = Regex::new(r"(mul\((\d+),(\d+)\)|do\(\)|don't\(\))").unwrap();
re.captures_iter(s)
.filter_map(|cap| match cap.get(0).map(|m| m.as_str()) {
Some(full_match) if full_match.starts_with("mul(") => cap[2]
.parse::<i32>()
.ok()
.zip(cap[3].parse::<i32>().ok())
.map(|(x, y)| Instruction::Mul(x, y)),
Some("do()") => Some(Instruction::Do),
Some("don't()") => Some(Instruction::Dont),
_ => None,
})
.collect()
}
#[cfg(test)]
mod test {
use aoc_lib::{answer::Answer, input, solution::Solution};
use super::Day3;
#[test]
fn test_a() {
let input =
input::read_file(&format!("{}day_03_a_test.txt", crate::FILES_PREFIX_TEST)).unwrap();
let answer = Day3.part_a(&input);
assert_eq!(<i32 as Into<Answer>>::into(161), answer);
}
#[test]
fn test_b() {
let input =
input::read_file(&format!("{}day_03_b_test.txt", crate::FILES_PREFIX_TEST)).unwrap();
let answer = Day3.part_b(&input);
assert_eq!(<i32 as Into<Answer>>::into(48), answer);
}
}