summaryrefslogtreecommitdiffstats
path: root/src/2021/15/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/2021/15/mod.rs')
-rw-r--r--src/2021/15/mod.rs79
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]