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 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);
|
||||||
|
|
Loading…
Reference in New Issue