Skip to content

Commit

Permalink
[2023] Complete day 17
Browse files Browse the repository at this point in the history
  • Loading branch information
connorslade committed Dec 17, 2023
1 parent 9b0b23a commit 446713c
Showing 1 changed file with 48 additions and 111 deletions.
159 changes: 48 additions & 111 deletions aoc_2023/src/day_17.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::{HashMap, VecDeque};

use common::{Answer, Solution};
use nd_vec::{vector, Vec2};

Expand Down Expand Up @@ -94,133 +96,68 @@ impl Solution for Day17 {

fn part_b(&self, input: &str) -> Answer {
let board = parse(input);
pathfind(&board, 4, 10).into()
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct State {
pos: Pos,
facing: Direction,
turn_distance: u8,
steps: u32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct State {
pos: Pos,
facing: Direction,
turn_distance: u8,
steps: u32,
}

let start = State {
pos: vector!(0, 0),
facing: Direction::Right,
turn_distance: 0,
steps: 0,
};
fn pathfind(board: &[Vec<u8>], lower: u8, upper: u8) -> u32 {
let mut res = u32::MAX;
let mut queue = VecDeque::new();
let mut visited = HashMap::new();

let path = pathfinding::directed::dijkstra::dijkstra(
&start,
|x| {
let mut next = Vec::new();
let end = vector!(board[0].len() - 1, board.len() - 1);
for dir in [Direction::Down, Direction::Right] {
let state = (vector!(0, 0), dir, 1);
queue.push_back((state, 0));
visited.insert(state, 0);
}

// Straight
if x.turn_distance < 10 {
if let Some(next_pos) = x.facing.advance(x.pos) {
if next_pos.x() < board[0].len() && next_pos.y() < board.len() {
let cell = board[next_pos.y()][next_pos.x()] as u32;
next.push((
State {
pos: next_pos,
facing: x.facing,
turn_distance: x.turn_distance + 1,
steps: x.steps + cell,
},
cell,
));
}
while let Some(((pos, facing, turn_distance), cost)) = queue.pop_front() {
let mut push = |dir: Direction, turn_distance: u8| {
if let Some(next) = dir.advance(pos) {
if next.y() < board.len() && next.x() < board[0].len() {
let state = (next, dir, turn_distance);
let cell = board[next.y()][next.x()] as u32;
let cost = cost + cell;

if !visited.contains_key(&state) || visited[&state] > cost {
queue.push_back((state, cost));
visited.insert(state, cost);
}
}
}
};

if x.turn_distance >= 3 {
// Left
let facing = x.facing.turn_left();
let mut pos = Some(x.pos);
let mut cell = 0;
for _ in 0..4 {
pos = pos.map(|pos| facing.advance(pos)).flatten();
if let Some(p) = pos {
if !(p.x() < board[0].len() && p.y() < board.len()) {
pos = None;
break;
}

cell += board[p.y()][p.x()] as u32;
}
}
if let Some(next_facing) = pos {
next.push((
State {
pos: next_facing,
facing: x.facing.turn_left(),
turn_distance: 3,
steps: x.steps + cell,
},
cell,
));
}

// Right
let facing = x.facing.turn_right();
let mut pos = Some(x.pos);
let mut cell = 0;
for _ in 0..4 {
pos = pos.map(|pos| facing.advance(pos)).flatten();
if let Some(p) = pos {
if !(p.x() < board[0].len() && p.y() < board.len()) {
pos = None;
break;
}

cell += board[p.y()][p.x()] as u32;
}
}
if let Some(next_facing) = pos {
if next_facing.x() < board[0].len() && next_facing.y() < board.len() {
next.push((
State {
pos: next_facing,
facing: x.facing.turn_right(),
turn_distance: 3,
steps: x.steps + cell,
},
cell,
));
}
}
}
if pos == end && turn_distance >= 4 {
res = res.min(cost);
continue;
}

next
},
|x| x.turn_distance >= 3 && x.pos == vector!(board[0].len() - 1, board.len() - 1),
)
.unwrap();

for (y, row) in board.iter().enumerate() {
for (x, cell) in row.iter().enumerate() {
let visited = path.0.iter().any(|state| state.pos == vector!(x, y));
if visited {
print!("\x1b[1;31m{cell}\x1b[0m");
} else {
print!("{cell}");
}
}
println!();
if turn_distance < upper {
push(facing, turn_distance + 1);
}

path.1.into()
if turn_distance >= lower {
push(facing.turn_left(), 1);
push(facing.turn_right(), 1);
}
}

res
}

fn parse(input: &str) -> Vec<Vec<u8>> {
input
.lines()
.map(|line| {
line.chars()
.map(|x| x.to_digit(10).unwrap() as u8)
.collect()
})
.map(|line| line.chars().map(|x| x as u8 - b'0').collect())
.collect::<Vec<_>>()
}

Expand Down

0 comments on commit 446713c

Please sign in to comment.