Skip to content

Commit 0d7bf8e

Browse files
committed
feat(11/2025): add cache for counting all paths and solve second part
1 parent fa96be1 commit 0d7bf8e

File tree

3 files changed

+19
-40
lines changed

3 files changed

+19
-40
lines changed

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
| [Day 8: Playground](src/solutions/year2025/day08.rs) | ⭐⭐ | 46.993 | 44.599 |
2222
| [Day 9: Movie Theater](src/solutions/year2025/day09.rs) || 0.387 | - |
2323
| [Day 10: Factory](src/solutions/year2025/day10.rs) | | - | - |
24-
| [Day 11: Reactor](src/solutions/year2025/day11.rs) | | 0.692 | - |
24+
| [Day 11: Reactor](src/solutions/year2025/day11.rs) | | 0.524 | 0.855 |
2525

2626
# 2024
2727

src/solutions/year2025/day11.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,13 @@ impl Solution for Day11 {
1515
let graph = self.parse(input);
1616
let all_paths: AllPaths<&str> = (&graph).into();
1717

18-
all_paths.paths(LABEL_YOU, LABEL_OUT).len().to_string()
18+
all_paths.count_paths(LABEL_YOU, LABEL_OUT).to_string()
1919
}
2020

2121
fn part_two(&self, input: &str) -> String {
2222
let graph = self.parse(input);
23-
// todo reverse graph for directed only
24-
// if undirected it is just the same?
2523
let all_paths: AllPaths<&str> = (&graph).into();
2624

27-
// find depth of every path and then pass it as parameter
28-
2925
let svr_dac = all_paths.count_paths(LABEL_SVR, LABEL_DAC);
3026
let dac_fft = all_paths.count_paths(LABEL_DAC, LABEL_FFT);
3127
let fft_out = all_paths.count_paths(LABEL_FFT, LABEL_OUT);

src/utils/graphs/all_paths.rs

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -94,59 +94,42 @@ where
9494
where
9595
E: IsEnd<T>,
9696
{
97-
self.count_paths_with_condition(start, end, |_: &VecDeque<T>| true)
98-
}
99-
100-
pub fn count_paths_with_condition<E>(
101-
&self,
102-
start: T,
103-
end: E,
104-
should_count_path: impl Fn(&VecDeque<T>) -> bool,
105-
) -> usize
106-
where
107-
E: IsEnd<T>,
108-
{
109-
let mut visited = HashSet::new();
97+
let mut cache: HashMap<T, usize> = HashMap::new();
11098
let mut path = VecDeque::new();
11199

112-
self.visit_and_count(start, &end, &mut visited, &mut path, &should_count_path)
100+
self.visit_and_count(start, &end, &mut cache, &mut path)
113101
}
114102

115-
fn visit_and_count<E, F>(
103+
fn visit_and_count<E>(
116104
&self,
117105
from: T,
118106
end: &E,
119-
visited: &mut HashSet<T>,
107+
cache: &mut HashMap<T, usize>,
120108
path: &mut VecDeque<T>,
121-
should_count_path: &F,
122109
) -> usize
123110
where
124111
E: IsEnd<T>,
125-
F: Fn(&VecDeque<T>) -> bool,
126112
{
127-
let mut count = 0usize;
128-
129-
visited.insert(from); // probably is not needed for graph
130113
path.push_back(from);
131114

132-
println!("{} {:?}", path.len(), path);
133-
134115
if end.is_end(&from) {
135-
if should_count_path(path) {
136-
count += 1;
137-
}
138-
} else {
139-
for p in (self.adjacency)(from) {
140-
if !visited.contains(&p) {
141-
count += self.visit_and_count(p, end, visited, path, should_count_path);
142-
}
143-
}
116+
return 1;
144117
}
145118

119+
if let Some(cache_value) = cache.get(&from) {
120+
return *cache_value;
121+
}
122+
123+
let result = (self.adjacency)(from)
124+
.iter()
125+
.map(|p| self.visit_and_count(*p, end, cache, path))
126+
.sum::<usize>();
127+
128+
cache.insert(from, result);
129+
146130
path.pop_back();
147-
visited.remove(&from);
148131

149-
count
132+
result
150133
}
151134
}
152135

0 commit comments

Comments
 (0)