day 18 pt2

This commit is contained in:
RussellChamp committed 2024-12-18 22:10:13 +00:00
1 parent 43fb676e64
commit 599b1a7fcf
2 files changed
+163

No files matched your search

+25
View File
@@ -0,0 +1,25 @@
5,4
4,2
4,5
3,0
2,1
6,3
2,4
1,5
0,6
3,3
2,6
5,1
1,2
5,5
2,5
6,5
1,4
0,4
6,4
1,1
6,1
1,0
0,5
1,6
2,0
+138
View File
@@ -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"));
}
}