tiny mini optimizations

This commit is contained in:
Jan-Bulthuis 2024-12-22 02:30:41 +01:00
parent 40b79950bd
commit cf5d423f50
1 changed files with 26 additions and 36 deletions

View File

@ -12,13 +12,7 @@ impl Path {
let mut path = [None, None, None, None, None, None]; let mut path = [None, None, None, None, None, None];
let mut i = 0; let mut i = 0;
while i < steps { while i < steps {
path[i] = Some(match buttons[i] { path[i] = Some(buttons[i]);
DirButton::Up => DirButton::Up,
DirButton::Down => DirButton::Down,
DirButton::Left => DirButton::Left,
DirButton::Right => DirButton::Right,
DirButton::A => DirButton::A,
});
i += 1; i += 1;
} }
let steps = steps + 1; let steps = steps + 1;
@ -123,7 +117,7 @@ const DIRBUTTON_PATHS: [[[Option<Path>; 2]; 5]; 5] = [
]; ];
impl DirButton { impl DirButton {
fn index(&self) -> usize { const fn index(&self) -> usize {
match self { match self {
DirButton::Up => 0, DirButton::Up => 0,
DirButton::Down => 1, DirButton::Down => 1,
@ -133,7 +127,7 @@ impl DirButton {
} }
} }
fn to(&self, other: &DirButton) -> &[Option<Path>; 2] { const fn paths_to(&self, other: &DirButton) -> &[Option<Path>; 2] {
&DIRBUTTON_PATHS[self.index()][other.index()] &DIRBUTTON_PATHS[self.index()][other.index()]
} }
} }
@ -154,7 +148,7 @@ enum NumButton {
} }
impl NumButton { impl NumButton {
fn pos(&self) -> (usize, usize) { const fn pos(&self) -> (usize, usize) {
match self { match self {
NumButton::One => (0, 2), NumButton::One => (0, 2),
NumButton::Two => (1, 2), NumButton::Two => (1, 2),
@ -170,7 +164,7 @@ impl NumButton {
} }
} }
fn to(&self, other: &NumButton) -> [Option<Path>; 2] { fn paths_to(&self, other: &NumButton) -> [Option<Path>; 2] {
let start = self.pos(); let start = self.pos();
let end = other.pos(); let end = other.pos();
@ -247,7 +241,7 @@ impl NumButton {
} }
} }
type Input = Vec<(usize, Vec<NumButton>)>; type Input = Vec<(DistanceSize, Vec<NumButton>)>;
#[aoc_generator(day21)] #[aoc_generator(day21)]
fn parse(input: &str) -> Input { fn parse(input: &str) -> Input {
@ -277,7 +271,8 @@ fn parse(input: &str) -> Input {
.collect() .collect()
} }
type DistanceMatrix = [[usize; 5]; 5]; type DistanceSize = u64;
type DistanceMatrix = [[DistanceSize; 5]; 5];
fn precompute_steps(steps: &mut [DistanceMatrix]) { fn precompute_steps(steps: &mut [DistanceMatrix]) {
if steps.len() == 1 { if steps.len() == 1 {
@ -297,7 +292,7 @@ fn precompute_steps(steps: &mut [DistanceMatrix]) {
buttons.iter().for_each(|start| { buttons.iter().for_each(|start| {
buttons.iter().for_each(|end| { buttons.iter().for_each(|end| {
steps[0][start.index()][end.index()] = start steps[0][start.index()][end.index()] = start
.to(end) .paths_to(end)
.iter() .iter()
.flatten() .flatten()
.map(|path| { .map(|path| {
@ -309,46 +304,41 @@ fn precompute_steps(steps: &mut [DistanceMatrix]) {
}) })
.0 .0
}) })
.fold(usize::MAX, |acc, next| acc.min(next)); .fold(DistanceSize::MAX, |acc, next| acc.min(next));
}); });
}); });
} }
fn shortest_dir_path(path: Path, steps: &mut [DistanceMatrix]) -> usize { fn shortest_dir_path(path: Path, steps: &mut [DistanceMatrix]) -> DistanceSize {
path.path path.path
.iter() .iter()
.flatten() .flatten()
.fold((0, &DirButton::A), |acc, next| { .fold((0, &DirButton::A), |acc, next| {
let sum = acc.0; (acc.0 + steps[0][acc.1.index()][next.index()], next)
let pos = acc.1;
let extension = steps[0][pos.index()][next.index()];
(sum + extension, next)
}) })
.0 .0
} }
fn shortest_path(path: &[NumButton], steps: &mut [DistanceMatrix]) -> usize { fn shortest_path(path: &[NumButton], steps: &mut [DistanceMatrix]) -> DistanceSize {
path.iter() path.iter()
.fold((0, &NumButton::A), |acc, end| { .fold((0, &NumButton::A), |acc, end| {
let sum = acc.0; (
let start = acc.1; acc.0
+ acc
let extension = start .1
.to(end) .paths_to(end)
.into_iter() .into_iter()
.flatten() .flatten()
.map(|path| shortest_dir_path(path, steps)) .map(|path| shortest_dir_path(path, steps))
.min() .fold(DistanceSize::MAX, |acc, next| acc.min(next)),
.unwrap(); end,
(sum + extension, end) )
}) })
.0 .0
} }
#[aoc(day21, part1)] #[aoc(day21, part1)]
fn part1(input: &Input) -> usize { fn part1(input: &Input) -> DistanceSize {
let mut steps = vec![[[1; 5]; 5]; 3]; let mut steps = vec![[[1; 5]; 5]; 3];
precompute_steps(&mut steps); precompute_steps(&mut steps);
@ -360,7 +350,7 @@ fn part1(input: &Input) -> usize {
} }
#[aoc(day21, part2)] #[aoc(day21, part2)]
fn part2(input: &Input) -> usize { fn part2(input: &Input) -> DistanceSize {
let mut steps = vec![[[1; 5]; 5]; 26]; let mut steps = vec![[[1; 5]; 5]; 26];
precompute_steps(&mut steps); precompute_steps(&mut steps);