tiny mini optimizations
This commit is contained in:
parent
40b79950bd
commit
cf5d423f50
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue