day16: improve perf again by going to i16 positions
All checks were successful
test / AoC 2024 (push) Successful in 5m29s

map dimensions fit in i16, so use those in data structures

make grid support generic position type as long as they implement to i64
This commit is contained in:
Keenan Tims 2024-12-16 01:06:02 -08:00
parent 755fbbc53d
commit 20e6889572
Signed by: ktims
GPG Key ID: 11230674D69038D4
2 changed files with 19 additions and 54 deletions

View File

@ -1,11 +1,14 @@
use aoc_runner_derive::aoc; use aoc_runner_derive::aoc;
use grid::{AsCoord2d, Coord2d, Grid}; use grid::Grid;
use std::{ use std::{
collections::{BinaryHeap, HashMap}, collections::{BinaryHeap, HashMap},
str::FromStr, str::FromStr,
usize, usize,
}; };
type CoordType = i16;
type Coord = (CoordType, CoordType);
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)]
enum FacingDirection { enum FacingDirection {
East, East,
@ -15,7 +18,7 @@ enum FacingDirection {
} }
impl FacingDirection { impl FacingDirection {
fn ofs(&self) -> (i32, i32) { fn ofs(&self) -> (CoordType, CoordType) {
match self { match self {
FacingDirection::East => (1, 0), FacingDirection::East => (1, 0),
FacingDirection::South => (0, 1), FacingDirection::South => (0, 1),
@ -35,7 +38,7 @@ impl FacingDirection {
#[derive(Clone, Eq, PartialEq, Debug)] #[derive(Clone, Eq, PartialEq, Debug)]
struct State { struct State {
cost: usize, cost: usize,
position: (i32, i32), position: Coord,
facing: FacingDirection, facing: FacingDirection,
} }
@ -58,7 +61,7 @@ impl PartialOrd for State {
#[derive(Clone, Eq, PartialEq, Debug)] #[derive(Clone, Eq, PartialEq, Debug)]
struct PathState { struct PathState {
state: State, state: State,
path: Vec<(i32, i32)>, path: Vec<Coord>,
} }
impl Ord for PathState { impl Ord for PathState {
@ -88,10 +91,10 @@ impl FromStr for Maze {
impl Maze { impl Maze {
fn dijkstra(&self) -> usize { fn dijkstra(&self) -> usize {
let (start_x, start_y) = self.map.find(&b'S').expect("can't find start"); let (start_x, start_y) = self.map.find(&b'S').expect("can't find start");
let start = (start_x as i32, start_y as i32); let start = (start_x as CoordType, start_y as CoordType);
let (finish_x, finish_y) = self.map.find(&b'E').expect("can't find finish"); let (finish_x, finish_y) = self.map.find(&b'E').expect("can't find finish");
let finish = (finish_x as i32, finish_y as i32); let finish = (finish_x as CoordType, finish_y as CoordType);
let mut distances = HashMap::new(); let mut distances = HashMap::new();
let mut queue = BinaryHeap::new(); let mut queue = BinaryHeap::new();
@ -134,7 +137,7 @@ impl Maze {
} }
usize::MAX usize::MAX
} }
fn path_dijkstra(&mut self) -> (usize, Vec<Vec<(i32, i32)>>) { fn path_dijkstra(&mut self) -> (usize, Vec<Vec<Coord>>) {
let (start_x, start_y) = self.map.find(&b'S').expect("can't find start"); let (start_x, start_y) = self.map.find(&b'S').expect("can't find start");
let start = (start_x.try_into().unwrap(), start_y.try_into().unwrap()); let start = (start_x.try_into().unwrap(), start_y.try_into().unwrap());
let (finish_x, finish_y) = self.map.find(&b'E').expect("can't find finish"); let (finish_x, finish_y) = self.map.find(&b'E').expect("can't find finish");

View File

@ -63,60 +63,22 @@ impl AsCoord2d for &Coord2d {
} }
} }
impl AsCoord2d for (i32, i32) { impl<T> AsCoord2d for (T, T)
where
T: Copy + TryInto<i64>,
<T as TryInto<i64>>::Error: Debug,
{
fn to_coord(self) -> Coord2d { fn to_coord(self) -> Coord2d {
Coord2d { Coord2d {
x: self.0.into(), x: self.0.try_into().unwrap(),
y: self.1.into(), y: self.1.try_into().unwrap(),
} }
} }
fn x(&self) -> i64 { fn x(&self) -> i64 {
self.0.into() self.0.try_into().unwrap()
} }
fn y(&self) -> i64 { fn y(&self) -> i64 {
self.1.into() self.1.try_into().unwrap()
}
}
impl AsCoord2d for (i64, i64) {
fn to_coord(self) -> Coord2d {
Coord2d { x: self.0, y: self.1 }
}
fn x(&self) -> i64 {
self.0
}
fn y(&self) -> i64 {
self.1
}
}
impl AsCoord2d for (usize, usize) {
fn to_coord(self) -> Coord2d {
Coord2d {
x: self.0 as i64,
y: self.1 as i64,
}
}
fn x(&self) -> i64 {
self.0 as i64
}
fn y(&self) -> i64 {
self.1 as i64
}
}
impl AsCoord2d for (u64, u64) {
fn to_coord(self) -> Coord2d {
Coord2d {
x: self.0 as i64,
y: self.1 as i64,
}
}
fn x(&self) -> i64 {
self.0 as i64
}
fn y(&self) -> i64 {
self.1 as i64
} }
} }