-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path17.rs
60 lines (50 loc) · 1.54 KB
/
17.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#![feature(test)]
use std::{cmp::Reverse, collections::BinaryHeap};
use aoc::grid::Direction;
type Input = Vec<Vec<u8>>;
fn setup(input: &str) -> Input {
input
.lines()
.map(|line| line.bytes().map(|b| b - b'0').collect())
.collect()
}
fn dijkstra<const MIN: usize, const MAX: usize>(input: &Input) -> u32 {
let h = input.len();
let w = input[0].len();
let mut queue = BinaryHeap::from_iter([
(Reverse(0), (0, 0), Direction::East),
(Reverse(0), (0, 0), Direction::South),
]);
let mut visited = vec![false; h * w * 4];
while let Some((Reverse(c), (x, y), pd)) = queue.pop() {
if x == input[0].len() - 1 && y == input.len() - 1 {
return c;
}
let i = (x + y * w) * 4 + pd as usize;
if visited[i] {
continue;
}
visited[i] = true;
queue.extend(
[pd.rotate_left(), pd.rotate_right()]
.into_iter()
.flat_map(|d| {
std::iter::successors(Some((c, x, y)), move |&(c, x, y)| {
let (x, y) = d.step(x, y, w, h)?;
Some((c + input[y][x] as u32, x, y))
})
.take(MAX + 1)
.skip(MIN)
.map(move |(c, x, y)| (Reverse(c), (x, y), d))
}),
);
}
panic!()
}
fn part1(input: &Input) -> u32 {
dijkstra::<1, 3>(input)
}
fn part2(input: &Input) -> u32 {
dijkstra::<4, 10>(input)
}
aoc::main!(2023, 17, ex: 1, 2[b]);