mirror of
https://github.com/RussellChamp/advent-of-code-2024-rust.git
synced 2026-10-27 23:52:29 +00:00
day 18 pt2
This commit is contained in:
1 parent
43fb676e64
commit
599b1a7fcf
2 files changed
+163
No files matched your search
+138
@@ -0,0 +1,138 @@
|
||||
use itertools::Itertools;
|
||||
|
||||
advent_of_code::solution!(18);
|
||||
|
||||
const GRID_HEIGHT: usize = 71;
|
||||
const GRID_WIDTH: usize = 71;
|
||||
|
||||
pub fn part_one(input: &str) -> Option<u32> {
|
||||
run_maze_pt1(input, GRID_HEIGHT, GRID_WIDTH, 1024)
|
||||
}
|
||||
|
||||
pub fn part_two(input: &str) -> Option<&str> {
|
||||
run_maze_pt2(input, GRID_HEIGHT, GRID_WIDTH, 1024)
|
||||
}
|
||||
|
||||
fn run_maze_pt1(input: &str, grid_height: usize, grid_width: usize, sim_steps: usize) -> Option<u32> {
|
||||
let mut grid = vec![vec![None; grid_height]; grid_width];
|
||||
let mut cost = vec![vec![None; grid_height]; grid_width];
|
||||
for (tick, line) in input.lines().take(sim_steps).enumerate() {
|
||||
let values = line.split(",").collect_vec();
|
||||
let col_idx = values[0].parse::<usize>().unwrap();
|
||||
let row_idx = values[1].parse::<usize>().unwrap();
|
||||
|
||||
grid[row_idx][col_idx] = Some(tick);
|
||||
}
|
||||
solve_maze_pt1(&grid, &mut cost, 0, 0, 0);
|
||||
let exit_cost = cost[grid_height-1][grid_width-1];
|
||||
|
||||
Some(exit_cost.unwrap() as u32)
|
||||
}
|
||||
|
||||
fn solve_maze_pt1(grid: &[Vec<Option<usize>>], cost: &mut [Vec<Option<usize>>], row_idx: usize, col_idx: usize, step: usize) {
|
||||
cost[row_idx][col_idx] = Some(step);
|
||||
|
||||
let grid_height = grid.len();
|
||||
let grid_width = grid[0].len();
|
||||
|
||||
for d in [(-1, 0), (1, 0), (0, -1), (0, 1)] {
|
||||
let new_row_idx = row_idx as isize + d.0;
|
||||
let new_col_idx = col_idx as isize + d.1;
|
||||
let can_step =
|
||||
(0..grid_height as isize).contains(&new_row_idx) &&
|
||||
(0..grid_width as isize).contains(&new_col_idx) &&
|
||||
Option::is_none(&grid[new_row_idx as usize][new_col_idx as usize]) &&
|
||||
(
|
||||
Option::is_none(&cost[new_row_idx as usize][new_col_idx as usize]) ||
|
||||
cost[new_row_idx as usize][new_col_idx as usize] > Some(step + 1)
|
||||
);
|
||||
|
||||
if can_step {
|
||||
solve_maze_pt1(grid, cost, new_row_idx as usize, new_col_idx as usize, step + 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn run_maze_pt2(input: &str, grid_height: usize, grid_width: usize, sim_steps: usize) -> Option<&str> {
|
||||
let mut grid = vec![vec![None; grid_height]; grid_width];
|
||||
let mut lines = input.lines();
|
||||
for (tick, line) in lines.by_ref().take(sim_steps).enumerate() {
|
||||
let values = line.split(",").collect_vec();
|
||||
let col_idx = values[0].parse::<usize>().unwrap();
|
||||
let row_idx = values[1].parse::<usize>().unwrap();
|
||||
|
||||
grid[row_idx][col_idx] = Some(tick);
|
||||
// print!(".");
|
||||
}
|
||||
// println!("\nDone!");
|
||||
|
||||
let mut last_path = vec![];
|
||||
|
||||
for (tick, line) in lines.by_ref().enumerate() {
|
||||
let values = line.split(",").collect_vec();
|
||||
let col_idx = values[0].parse::<usize>().unwrap();
|
||||
let row_idx = values[1].parse::<usize>().unwrap();
|
||||
grid[row_idx][col_idx] = Some(tick);
|
||||
|
||||
let mut cost = vec![vec![None; grid_height]; grid_width];
|
||||
|
||||
if last_path.len() == 0 || last_path.contains(&(row_idx, col_idx)) {
|
||||
// println!("SOLVE! {line}");
|
||||
solve_maze_pt1(&grid, &mut cost, 0, 0, 0);
|
||||
|
||||
if Option::is_none(&cost[grid_height-1][grid_width-1]) {
|
||||
return Some(line);
|
||||
} else {
|
||||
last_path = get_last_path(&cost, grid_height, grid_width);
|
||||
}
|
||||
} else {
|
||||
// println!("SKIP! {line}");
|
||||
}
|
||||
};
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn get_last_path(cost_map: &[Vec<Option<usize>>], grid_height: usize, grid_width: usize) -> Vec<(usize, usize)> {
|
||||
let mut path = vec![(grid_height - 1, grid_width - 1)];
|
||||
|
||||
let mut cur_pos = (grid_height - 1, grid_width - 1);
|
||||
|
||||
// println!("{:#?}", cost_map);
|
||||
while cur_pos.0 != 0 || cur_pos.1 != 0 {
|
||||
let step_down = [(-1, 0), (1, 0), (0, -1), (0, 1)].iter().find_map(|d| {
|
||||
let new_row = cur_pos.0 as isize + d.0;
|
||||
let new_col = cur_pos.1 as isize + d.1;
|
||||
if (0..grid_height as isize).contains(&new_row) &&
|
||||
(0..grid_width as isize).contains(&new_col) &&
|
||||
(
|
||||
Option::is_some(&cost_map[new_row as usize][new_col as usize]) &&
|
||||
cost_map[new_row as usize][new_col as usize].unwrap() == cost_map[cur_pos.0][cur_pos.1].unwrap() - 1
|
||||
) {
|
||||
Some((new_row as usize, new_col as usize))
|
||||
} else { None }
|
||||
});
|
||||
path.push(step_down.unwrap());
|
||||
cur_pos = step_down.unwrap();
|
||||
}
|
||||
|
||||
path
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part_one() {
|
||||
let result = run_maze_pt1(&advent_of_code::template::read_file("examples", DAY), 7, 7, 12);
|
||||
assert_eq!(result, Some(22));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_two() {
|
||||
let binding = advent_of_code::template::read_file("examples", DAY);
|
||||
let result = run_maze_pt2(&binding, 7, 7, 12);
|
||||
assert_eq!(result, Some("6,1"));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user