Skip to content

Commit f5ca114

Browse files
Day 7
1 parent dcc45a5 commit f5ca114

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

data/examples/07.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
190: 10 19
2+
3267: 81 40 27
3+
83: 17 5
4+
156: 15 6
5+
7290: 6 8 6 15
6+
161011: 16 10 13
7+
192: 17 8 14
8+
21037: 9 7 18 13
9+
292: 11 6 16 20

src/bin/07.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
use advent_of_code::template::parse::lines;
2+
3+
advent_of_code::solution!(7);
4+
5+
fn dfs1(target: u64, prior: u64, eqn: &[u64]) -> bool {
6+
match eqn.split_first() {
7+
None => prior == target,
8+
Some((x, tail)) => dfs1(target, prior + x, tail) || dfs1(target, prior * x, tail),
9+
}
10+
}
11+
12+
const POW10: &[u64] = &[
13+
1,
14+
10,
15+
100,
16+
1_000,
17+
10_000,
18+
100_000,
19+
1_000_000,
20+
10_000_000,
21+
100_000_000,
22+
1_000_000_000,
23+
10_000_000_000,
24+
100_000_000_000,
25+
1_000_000_000_000,
26+
10_000_000_000_000,
27+
100_000_000_000_000,
28+
1_000_000_000_000_000,
29+
10_000_000_000_000_000,
30+
100_000_000_000_000_000,
31+
1_000_000_000_000_000_000,
32+
10_000_000_000_000_000_000,
33+
];
34+
35+
fn dfs2(target: u64, prior: u64, eqn: &[(u64, usize)]) -> bool {
36+
prior <= target
37+
&& match eqn.split_first() {
38+
None => prior == target,
39+
Some((&(x, len), tail)) => {
40+
dfs2(target, prior + x, tail)
41+
|| dfs2(target, prior * x, tail)
42+
|| dfs2(target, (prior * POW10[len]) + x, tail)
43+
}
44+
}
45+
}
46+
47+
pub fn part_one(input: &str) -> Option<u64> {
48+
let mut res = 0;
49+
for line in lines(input) {
50+
let mut splita = line.split(':');
51+
let target = splita.next().unwrap().parse::<u64>().unwrap();
52+
let rest = splita.next().unwrap();
53+
let eqn = rest
54+
.split(' ')
55+
.filter(|s| !s.is_empty())
56+
.map(|s| s.parse::<u64>().unwrap())
57+
.collect::<Vec<u64>>();
58+
let (&init, tail) = eqn.split_first().unwrap();
59+
if dfs1(target, init, tail) {
60+
res += target;
61+
}
62+
}
63+
64+
Some(res)
65+
}
66+
67+
pub fn part_two(input: &str) -> Option<u64> {
68+
let mut res = 0;
69+
for line in lines(input) {
70+
let mut splita = line.split(':');
71+
let target = splita.next().unwrap().parse::<u64>().unwrap();
72+
let rest = splita.next().unwrap();
73+
let eqn = rest
74+
.split(' ')
75+
.filter(|s| !s.is_empty())
76+
.map(|s| (s.parse::<u64>().unwrap(), s.len()))
77+
.collect::<Vec<(u64, usize)>>();
78+
let (&(init, _), tail) = eqn.split_first().unwrap();
79+
if dfs2(target, init, tail) {
80+
res += target;
81+
}
82+
}
83+
84+
Some(res)
85+
}
86+
87+
#[cfg(test)]
88+
mod tests {
89+
use super::*;
90+
91+
#[test]
92+
fn test_part_one() {
93+
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
94+
assert_eq!(result, Some(3749));
95+
}
96+
97+
#[test]
98+
fn test_part_two() {
99+
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
100+
assert_eq!(result, Some(11387));
101+
}
102+
}

0 commit comments

Comments
 (0)