Skip to content

Commit 00c13a9

Browse files
committed
feat(21/2024): add memo
1 parent 7fdaeb8 commit 00c13a9

File tree

2 files changed

+41
-22
lines changed

2 files changed

+41
-22
lines changed

readme.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
| [Day 18: RAM Run](src/solutions/year2024/day18.rs) | ⭐⭐ | 2.487 | 204.885 |
3232
| [Day 19: Linen Layout](src/solutions/year2024/day19.rs) | ⭐⭐ | 2.923 | 22.751 |
3333
| [Day 20: Race Condition](src/solutions/year2024/day20.rs) | ⭐⭐ | 7.355 | 280.627 |
34-
| [Day 21: Keypad Conundrum](src/solutions/year2024/day21.rs) || 1.610 | - |
34+
| [Day 21: Keypad Conundrum](src/solutions/year2024/day21.rs) || 0.454 | - |
3535

3636
# 2023
3737

src/solutions/year2024/day21.rs

+40-21
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ use crate::utils::point::Point;
77
use itertools::Itertools;
88
use std::collections::HashMap;
99
use std::fmt::{Display, Formatter};
10+
use std::iter::repeat;
1011

1112
type Positions = HashMap<u8, Point>;
1213
type Adjacent = HashMap<Point, Vec<Point>>;
14+
type Memo = HashMap<(char, char, usize), String>;
1315

1416
const NUM_PAD: &str = r#"789
1517
456
@@ -26,27 +28,33 @@ pub struct Day21;
2628

2729
impl Solution for Day21 {
2830
fn part_one(&self, input: &str) -> String {
29-
let pads = vec![Pad::numeric(), Pad::key(), Pad::key()];
31+
self.solve(input, 2).to_string()
32+
}
33+
34+
fn part_two(&self, input: &str) -> String {
35+
self.solve(input, 25).to_string()
36+
}
37+
}
38+
39+
impl Day21 {
40+
fn solve(&self, input: &str, keypad_count: usize) -> usize {
41+
let mut pads = vec![Pad::numeric()];
42+
let mut memo = Memo::new();
43+
44+
pads.extend(repeat(Pad::key()).take(keypad_count));
3045

3146
input
3247
.lines()
3348
.map(|line| {
34-
let path_len = self.path(line, &pads).chars().count();
49+
let path_len = self.path(line, &pads, &mut memo).chars().count();
3550
let num: usize = line.trim_end_matches('A').parse().unwrap();
3651

3752
num * path_len
3853
})
3954
.sum::<usize>()
40-
.to_string()
4155
}
4256

43-
fn part_two(&self, _input: &str) -> String {
44-
String::from('0')
45-
}
46-
}
47-
48-
impl Day21 {
49-
fn path(&self, code: &str, pads: &[Pad]) -> String {
57+
fn path(&self, code: &str, pads: &[Pad], memo: &mut Memo) -> String {
5058
if pads.is_empty() {
5159
return code.to_string();
5260
}
@@ -58,11 +66,20 @@ impl Day21 {
5866
code.chars()
5967
.tuple_windows()
6068
.map(|(from, to)| {
61-
self.all_shortest_paths_between_buttons(from, to, pad)
69+
if let Some(path) = memo.get(&(from, to, pad_left.len())) {
70+
return path.clone();
71+
}
72+
73+
let shortest_path = self
74+
.all_shortest_paths_between_buttons(from, to, pad)
6275
.iter()
63-
.map(|path| self.path(path, pad_left))
76+
.map(|path| self.path(path, pad_left, memo))
6477
.min_by_key(|path| path.chars().count())
65-
.unwrap()
78+
.unwrap();
79+
80+
memo.insert((from, to, pad_left.len()), shortest_path.clone());
81+
82+
shortest_path
6683
})
6784
.collect()
6885
}
@@ -121,6 +138,7 @@ impl Display for Key {
121138
}
122139
}
123140

141+
#[derive(Clone)]
124142
struct Pad {
125143
positions: Positions,
126144
adjacent: Adjacent,
@@ -182,7 +200,7 @@ impl Pad {
182200

183201
#[cfg(test)]
184202
mod tests {
185-
use crate::solutions::year2024::day21::{Day21, Pad};
203+
use crate::solutions::year2024::day21::{Day21, Memo, Pad};
186204
use crate::solutions::Solution;
187205

188206
const EXAMPLE: &str = r#"029A
@@ -199,12 +217,13 @@ mod tests {
199217
#[test]
200218
fn path_len() {
201219
let pads = vec![Pad::numeric(), Pad::key(), Pad::key()];
202-
203-
assert_eq!(68, Day21.path("029A", &pads).len());
204-
assert_eq!(60, Day21.path("980A", &pads).len());
205-
assert_eq!(68, Day21.path("179A", &pads).len());
206-
assert_eq!(64, Day21.path("456A", &pads).len());
207-
assert_eq!(64, Day21.path("379A", &pads).len());
208-
assert_eq!(78, Day21.path("739A", &pads).len());
220+
let mut memo = Memo::new();
221+
222+
assert_eq!(68, Day21.path("029A", &pads, &mut memo).len());
223+
assert_eq!(60, Day21.path("980A", &pads, &mut memo).len());
224+
assert_eq!(68, Day21.path("179A", &pads, &mut memo).len());
225+
assert_eq!(64, Day21.path("456A", &pads, &mut memo).len());
226+
assert_eq!(64, Day21.path("379A", &pads, &mut memo).len());
227+
assert_eq!(78, Day21.path("739A", &pads, &mut memo).len());
209228
}
210229
}

0 commit comments

Comments
 (0)