diff options
Diffstat (limited to 'src/2021/15/mod.rs')
-rw-r--r-- | src/2021/15/mod.rs | 79 |
1 files changed, 34 insertions, 45 deletions
diff --git a/src/2021/15/mod.rs b/src/2021/15/mod.rs index efb2716..15b05fb 100644 --- a/src/2021/15/mod.rs +++ b/src/2021/15/mod.rs @@ -1,69 +1,58 @@ use crate::prelude::*; -fn dijkstra(map: &Grid<u8>) -> i64 { - let mut to_visit: priority_queue::PriorityQueue<_, _> = (0..map.rows().0) - .flat_map(|row| { - (0..map.cols().0).map(move |col| (Row(row), Col(col))) - }) - .map(|pos| { - ( - pos, - std::cmp::Reverse(if pos == (Row(0), Col(0)) { - 0 - } else { - i64::max_value() - }), - ) - }) - .collect(); +pub struct Map { + grid: Grid<u8>, +} - while let Some(((row, col), std::cmp::Reverse(distance))) = to_visit.pop() - { - if row == Row(map.rows().0 - 1) && col == Col(map.cols().0 - 1) { - return distance; - } +impl crate::graph::Graph<(Row, Col), (Row, Col)> for Map { + type Edges = crate::grid::Adjacent; - for neighbor in map.adjacent(row, col, false) { - if to_visit.get(&neighbor).is_some() { - let new_distance = - distance + i64::from(map[neighbor.0][neighbor.1]); - if new_distance < to_visit.get_priority(&neighbor).unwrap().0 - { - to_visit.change_priority( - &neighbor, - std::cmp::Reverse(new_distance), - ); - } - } - } + fn edges(&self, v: (Row, Col)) -> Self::Edges { + self.grid.adjacent(v.0, v.1, false) + } + + fn edge(&self, _v: (Row, Col), e: (Row, Col)) -> ((Row, Col), i64) { + (e, i64::from(self.grid[e.0][e.1])) } - unreachable!() } -pub fn parse(fh: File) -> Result<Grid<u8>> { - Ok(parse::digit_grid(parse::lines(fh))) +pub fn parse(fh: File) -> Result<Map> { + Ok(Map { + grid: parse::digit_grid(parse::lines(fh)), + }) } -pub fn part1(grid: Grid<u8>) -> Result<i64> { - Ok(dijkstra(&grid)) +pub fn part1(map: Map) -> Result<i64> { + Ok(map + .dijkstra( + (Row(0), Col(0)), + (map.grid.rows() - 1, map.grid.cols() - 1), + ) + .0) } -pub fn part2(grid: Grid<u8>) -> Result<i64> { +pub fn part2(map: Map) -> Result<i64> { let mut large_grid = Grid::default(); - large_grid.grow(Row(grid.rows().0 * 5), Col(grid.cols().0 * 5)); + large_grid.grow(Row(map.grid.rows().0 * 5), Col(map.grid.cols().0 * 5)); for lrow in 0..5 { for lcol in 0..5 { - for ((Row(row), Col(col)), val) in grid.indexed_cells() { + for ((Row(row), Col(col)), val) in map.grid.indexed_cells() { let mut val = val + lrow + lcol; while val > 9 { val -= 9; } - large_grid[Row(usize::from(lrow) * grid.rows().0 + row)] - [Col(usize::from(lcol) * grid.cols().0 + col)] = val; + large_grid[Row(usize::from(lrow) * map.grid.rows().0 + row)] + [Col(usize::from(lcol) * map.grid.cols().0 + col)] = val; } } } - Ok(dijkstra(&large_grid)) + let large_map = Map { grid: large_grid }; + Ok(large_map + .dijkstra( + (Row(0), Col(0)), + (large_map.grid.rows() - 1, large_map.grid.cols() - 1), + ) + .0) } #[test] |