Skip to content

Commit 5782dbc

Browse files
committed
[2025] Cleanup day 11
1 parent 96ce7af commit 5782dbc

File tree

1 file changed

+42
-60
lines changed

1 file changed

+42
-60
lines changed

aoc_2025/src/day_11.rs

Lines changed: 42 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -5,84 +5,66 @@ use common::{Answer, solution};
55
solution!("Reactor", 11);
66

77
fn part_a(input: &str) -> Answer {
8-
let mut map = HashMap::new();
9-
10-
for line in input.lines() {
11-
let (from, to) = line.split_once(": ").unwrap();
12-
let to = to.split_whitespace().collect::<Vec<_>>();
13-
map.insert(from, to);
14-
}
15-
16-
fn count_paths(map: &HashMap<&str, Vec<&str>>, current: &str) -> u64 {
17-
if current == "out" {
18-
return 1;
19-
}
8+
count_paths(&mut HashMap::new(), &parse(input), "you", [true; _]).into()
9+
}
2010

21-
let mut out = 0;
11+
fn part_b(input: &str) -> Answer {
12+
count_paths(&mut HashMap::new(), &parse(input), "svr", [false; _]).into()
13+
}
2214

23-
for child in &map[current] {
24-
out += count_paths(map, child);
25-
}
15+
fn count_paths<'a>(
16+
memo: &mut HashMap<(&'a str, [bool; 2]), u64>,
17+
map: &HashMap<&'a str, Vec<&'a str>>,
18+
current: &'a str,
19+
seen @ [fft, dac]: [bool; 2],
20+
) -> u64 {
21+
let entry = (current, seen);
22+
if let Some(memo) = memo.get(&entry) {
23+
return *memo;
24+
}
2625

27-
out
26+
if current == "out" {
27+
return (fft && dac) as u64;
2828
}
2929

30-
count_paths(&map, "you").into()
30+
let seen = [fft || current == "fft", dac || current == "dac"];
31+
let out = (map[current].iter())
32+
.map(|child| count_paths(memo, map, child, seen))
33+
.sum();
34+
35+
memo.insert(entry, out);
36+
out
3137
}
3238

33-
fn part_b(input: &str) -> Answer {
39+
fn parse(input: &str) -> HashMap<&str, Vec<&str>> {
3440
let mut map = HashMap::new();
35-
3641
for line in input.lines() {
3742
let (from, to) = line.split_once(": ").unwrap();
3843
let to = to.split_whitespace().collect::<Vec<_>>();
3944
map.insert(from, to);
4045
}
4146

42-
fn count_paths<'a>(
43-
memo: &mut HashMap<(&'a str, bool, bool), u64>,
44-
map: &HashMap<&str, Vec<&'a str>>,
45-
current: &'a str,
46-
mut fft: bool,
47-
mut dac: bool,
48-
) -> u64 {
49-
let key = (current, fft, dac);
50-
if let Some(memo) = memo.get(&key) {
51-
return *memo;
52-
}
53-
54-
if current == "out" {
55-
if fft && dac {
56-
return 1;
57-
}
58-
return 0;
59-
}
60-
61-
if current == "fft" {
62-
fft = true;
63-
}
64-
65-
if current == "dac" {
66-
dac = true;
67-
}
68-
69-
let mut out = 0;
70-
for child in &map[current] {
71-
out += count_paths(memo, map, child, fft, dac);
72-
}
73-
74-
memo.insert(key, out);
75-
out
76-
}
77-
78-
count_paths(&mut HashMap::new(), &map, "svr", false, false).into()
47+
map
7948
}
8049

8150
#[cfg(test)]
8251
mod test {
8352
use indoc::indoc;
8453

85-
const CASE: &str = indoc! {"
54+
const CASE_A: &str = indoc! {"
55+
aaa: you hhh
56+
you: bbb ccc
57+
bbb: ddd eee
58+
ccc: ddd eee fff
59+
ddd: ggg
60+
eee: out
61+
fff: out
62+
ggg: out
63+
hhh: ccc fff iii
64+
iii: out
65+
"};
66+
67+
const CASE_B: &str = indoc! {"
8668
svr: aaa bbb
8769
aaa: fft
8870
fft: ccc
@@ -100,11 +82,11 @@ mod test {
10082

10183
#[test]
10284
fn part_a() {
103-
assert_eq!(super::part_a(CASE), 5.into());
85+
assert_eq!(super::part_a(CASE_A), 5.into());
10486
}
10587

10688
#[test]
10789
fn part_b() {
108-
assert_eq!(super::part_b(CASE), 2.into());
90+
assert_eq!(super::part_b(CASE_B), 2.into());
10991
}
11092
}

0 commit comments

Comments
 (0)