Skip to content

Commit f4b5b74

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

File tree

1 file changed

+45
-51
lines changed

1 file changed

+45
-51
lines changed

aoc_2025/src/day_11.rs

Lines changed: 45 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,87 +2,81 @@ use std::collections::HashMap;
22

33
use common::{Answer, solution};
44

5+
type Graph<'a> = HashMap<&'a str, Vec<&'a str>>;
6+
57
solution!("Reactor", 11);
68

79
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 {
10+
fn count_paths(map: &Graph, current: &str) -> u64 {
1711
if current == "out" {
1812
return 1;
1913
}
2014

21-
let mut out = 0;
22-
23-
for child in &map[current] {
24-
out += count_paths(map, child);
25-
}
26-
27-
out
15+
(map[current].iter())
16+
.map(|child| count_paths(map, child))
17+
.sum()
2818
}
2919

30-
count_paths(&map, "you").into()
20+
count_paths(&parse(input), "you").into()
3121
}
3222

3323
fn part_b(input: &str) -> Answer {
34-
let mut map = HashMap::new();
35-
36-
for line in input.lines() {
37-
let (from, to) = line.split_once(": ").unwrap();
38-
let to = to.split_whitespace().collect::<Vec<_>>();
39-
map.insert(from, to);
40-
}
41-
4224
fn count_paths<'a>(
43-
memo: &mut HashMap<(&'a str, bool, bool), u64>,
44-
map: &HashMap<&str, Vec<&'a str>>,
25+
memo: &mut HashMap<(&'a str, (bool, bool)), u64>,
26+
map: &Graph<'a>,
4527
current: &'a str,
46-
mut fft: bool,
47-
mut dac: bool,
28+
(fft, dac): (bool, bool),
4829
) -> u64 {
49-
let key = (current, fft, dac);
50-
if let Some(memo) = memo.get(&key) {
30+
let entry = (current, (fft, dac));
31+
if let Some(memo) = memo.get(&entry) {
5132
return *memo;
5233
}
5334

5435
if current == "out" {
55-
if fft && dac {
56-
return 1;
57-
}
58-
return 0;
36+
return (fft && dac) as u64;
5937
}
6038

61-
if current == "fft" {
62-
fft = true;
63-
}
39+
let seen = (fft || current == "fft", dac || current == "dac");
40+
let out = (map[current].iter())
41+
.map(|child| count_paths(memo, map, child, seen))
42+
.sum();
6443

65-
if current == "dac" {
66-
dac = true;
67-
}
44+
memo.insert(entry, out);
45+
out
46+
}
6847

69-
let mut out = 0;
70-
for child in &map[current] {
71-
out += count_paths(memo, map, child, fft, dac);
72-
}
48+
count_paths(&mut HashMap::new(), &parse(input), "svr", (false, false)).into()
49+
}
7350

74-
memo.insert(key, out);
75-
out
51+
fn parse(input: &str) -> HashMap<&str, Vec<&str>> {
52+
let mut map = HashMap::new();
53+
for line in input.lines() {
54+
let (from, to) = line.split_once(": ").unwrap();
55+
let to = to.split_whitespace().collect::<Vec<_>>();
56+
map.insert(from, to);
7657
}
7758

78-
count_paths(&mut HashMap::new(), &map, "svr", false, false).into()
59+
map
7960
}
8061

8162
#[cfg(test)]
8263
mod test {
8364
use indoc::indoc;
8465

85-
const CASE: &str = indoc! {"
66+
const CASE_A: &str = indoc! {"
67+
aaa: you hhh
68+
you: bbb ccc
69+
bbb: ddd eee
70+
ccc: ddd eee fff
71+
ddd: ggg
72+
eee: out
73+
fff: out
74+
ggg: out
75+
hhh: ccc fff iii
76+
iii: out
77+
"};
78+
79+
const CASE_B: &str = indoc! {"
8680
svr: aaa bbb
8781
aaa: fft
8882
fft: ccc
@@ -100,11 +94,11 @@ mod test {
10094

10195
#[test]
10296
fn part_a() {
103-
assert_eq!(super::part_a(CASE), 5.into());
97+
assert_eq!(super::part_a(CASE_A), 5.into());
10498
}
10599

106100
#[test]
107101
fn part_b() {
108-
assert_eq!(super::part_b(CASE), 2.into());
102+
assert_eq!(super::part_b(CASE_B), 2.into());
109103
}
110104
}

0 commit comments

Comments
 (0)