[Rust/2023/17] Add solution

This commit is contained in:
Felix Bargfeldt 2023-12-17 14:48:24 +01:00
parent a12b0cca76
commit 7e481f6aea
Signed by: Defelo
GPG key ID: 2A05272471204DD3
10 changed files with 121 additions and 10 deletions

File diff suppressed because one or more lines are too long

View file

@ -4,15 +4,15 @@ use aoc::{grid::Direction, iter_ext::IterExt};
type Input = Vec<Vec<u8>>;
struct CoordIterator<'a> {
struct CoordIterator {
x: usize,
y: usize,
width: usize,
height: usize,
direction: &'a Direction,
direction: Direction,
}
impl Iterator for CoordIterator<'_> {
impl Iterator for CoordIterator {
type Item = (usize, usize);
fn next(&mut self) -> Option<Self::Item> {

60
Rust/2023/17.rs Normal file
View file

@ -0,0 +1,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]);

View file

@ -272,3 +272,6 @@ path = "2023/15.rs"
[[bin]]
name = "2023_16"
path = "2023/16.rs"
[[bin]]
name = "2023_17"
path = "2023/17.rs"

View file

@ -1,4 +1,4 @@
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Direction {
North,
East,
@ -7,7 +7,7 @@ pub enum Direction {
}
impl Direction {
pub fn step(&self, x: usize, y: usize, width: usize, height: usize) -> Option<(usize, usize)> {
pub fn step(self, x: usize, y: usize, width: usize, height: usize) -> Option<(usize, usize)> {
Some(match self {
Direction::North if y > 0 => (x, y - 1),
Direction::East if x < width - 1 => (x + 1, y),
@ -17,7 +17,7 @@ impl Direction {
})
}
pub fn step_signed(&self, (x, y): (isize, isize)) -> (isize, isize) {
pub fn step_signed(self, (x, y): (isize, isize)) -> (isize, isize) {
match self {
Direction::North => (x, y - 1),
Direction::East => (x + 1, y),
@ -26,8 +26,35 @@ impl Direction {
}
}
pub fn iter() -> std::slice::Iter<'static, Direction> {
[Self::North, Self::East, Self::South, Self::West].iter()
pub fn invert(self) -> Self {
match self {
Direction::North => Direction::South,
Direction::East => Direction::West,
Direction::South => Direction::North,
Direction::West => Direction::East,
}
}
pub fn rotate_left(self) -> Self {
match self {
Direction::North => Direction::West,
Direction::East => Direction::North,
Direction::South => Direction::East,
Direction::West => Direction::South,
}
}
pub fn rotate_right(self) -> Self {
match self {
Direction::North => Direction::East,
Direction::East => Direction::South,
Direction::South => Direction::West,
Direction::West => Direction::North,
}
}
pub fn iter() -> impl Iterator<Item = Self> {
[Self::North, Self::East, Self::South, Self::West].into_iter()
}
}

13
examples/2023/17/1 Normal file
View file

@ -0,0 +1,13 @@
2413432311323
3215453535623
3255245654254
3446585845452
4546657867536
1438598798454
4457876987766
3637877979653
4654967986887
4564679986453
1224686865563
2546548887735
4322674655533

1
examples/2023/17/1.1 Normal file
View file

@ -0,0 +1 @@
102

1
examples/2023/17/1.2 Normal file
View file

@ -0,0 +1 @@
94

5
examples/2023/17/2 Normal file
View file

@ -0,0 +1,5 @@
111111111111
999999999991
999999999991
999999999991
999999999991

1
examples/2023/17/2.2 Normal file
View file

@ -0,0 +1 @@
71