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