mirror of
https://github.com/RussellChamp/advent-of-code-2024-rust.git
synced 2026-10-27 23:52:29 +00:00
day 16 pt2
This commit is contained in:
1 parent
58de7c1eaf
commit
9a1cbcc8ee
3 files changed
+146
-3
No files matched your search
@@ -0,0 +1,17 @@
|
||||
#################
|
||||
#...#...#...#..E#
|
||||
#.#.#.#.#.#.#.#.#
|
||||
#.#.#.#...#...#.#
|
||||
#.#.#.#.###.#.#.#
|
||||
#...#.#.#.....#.#
|
||||
#.#.#.#.#.#####.#
|
||||
#.#...#.#.#.....#
|
||||
#.#.#####.#.###.#
|
||||
#.#.#.......#...#
|
||||
#.#.###.#####.###
|
||||
#.#.#...#.....#.#
|
||||
#.#.#.#####.###.#
|
||||
#.#.#.........#.#
|
||||
#.#.#.#########.#
|
||||
#S#.............#
|
||||
#################
|
||||
@@ -0,0 +1,15 @@
|
||||
###############
|
||||
#.......#....E#
|
||||
#.#.###.#.###.#
|
||||
#.....#.#...#.#
|
||||
#.###.#####.#.#
|
||||
#.#.#.......#.#
|
||||
#.#.#####.###.#
|
||||
#...........#.#
|
||||
###.#.#####.#.#
|
||||
#...#.....#.#.#
|
||||
#.#.#.###.#.#.#
|
||||
#.....#...#.#.#
|
||||
#.###.#.#.#.#.#
|
||||
#S..#.....#...#
|
||||
###############
|
||||
+114
-3
@@ -1,11 +1,115 @@
|
||||
use std::u32::MAX;
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
advent_of_code::solution!(16);
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(PartialEq)]
|
||||
enum TileObject {
|
||||
Start,
|
||||
End,
|
||||
Empty,
|
||||
Wall
|
||||
}
|
||||
|
||||
fn get_tile_object(c: char) -> TileObject {
|
||||
match c {
|
||||
'.' => TileObject::Empty,
|
||||
'#' => TileObject::Wall,
|
||||
'S' => TileObject::Start,
|
||||
'E' => TileObject::End,
|
||||
_ => panic!()
|
||||
}
|
||||
}
|
||||
|
||||
struct Cost {
|
||||
up: u32,
|
||||
down: u32,
|
||||
left: u32,
|
||||
right: u32,
|
||||
}
|
||||
|
||||
pub fn part_one(input: &str) -> Option<u32> {
|
||||
let grid = input.lines().map(|l| {
|
||||
l.chars().map(|c| get_tile_object(c)).collect_vec()
|
||||
}).collect_vec();
|
||||
|
||||
let grid_height = grid.len();
|
||||
let grid_width = grid[0].len();
|
||||
|
||||
let start_pos = grid.iter().enumerate().find_map(|(row_idx, row)| {
|
||||
row.iter().enumerate().find_map(|(col_idx, t)| if *t == TileObject::Start { Some((row_idx, col_idx)) } else { None })
|
||||
}).unwrap();
|
||||
|
||||
let mut score_card: Vec<Vec<Option<u32>>> = vec![vec![None; grid_width]; grid_height];
|
||||
|
||||
// From the starting position facing EAST
|
||||
score_card[start_pos.0][start_pos.1] = Some(0);
|
||||
explore(&grid, &mut score_card, start_pos, Cost { up: 1001, down: 1001, left: MAX, right: 1 });
|
||||
|
||||
let end_pos = grid.iter().enumerate().find_map(|(row_idx, row)| {
|
||||
row.iter().enumerate().find_map(|(col_idx, t)| if *t == TileObject::End { Some((row_idx, col_idx)) } else { None })
|
||||
}).unwrap();
|
||||
|
||||
let end_score = score_card[end_pos.0][end_pos.1].unwrap_or(0);
|
||||
Some(end_score)
|
||||
}
|
||||
|
||||
pub fn part_two(_input: &str) -> Option<u32> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn part_two(input: &str) -> Option<u32> {
|
||||
None
|
||||
fn explore(grid: &Vec<Vec<TileObject>>, score_card: &mut Vec<Vec<Option<u32>>>, pos: (usize, usize), move_cost: Cost) {
|
||||
if grid[pos.0][pos.1] == TileObject::Wall { return; }
|
||||
|
||||
let grid_height = grid.len();
|
||||
let grid_width = grid[0].len();
|
||||
|
||||
let pos_score = score_card[pos.0][pos.1].unwrap();
|
||||
|
||||
let get_step = |row_idx, col_idx| -> Option<(usize, usize)> {
|
||||
if !(0..grid_height as isize).contains(&row_idx) || !(0..grid_width as isize).contains(&col_idx) { return None }
|
||||
else if grid[row_idx as usize][col_idx as usize] == TileObject::Wall { return None }
|
||||
else { return Some((row_idx as usize, col_idx as usize)) }
|
||||
};
|
||||
|
||||
// UP
|
||||
if let Some(step) = get_step(pos.0 as isize - 1, pos.1 as isize) {
|
||||
let next_cost = score_card[step.0][step.1];
|
||||
if move_cost.up != MAX && (Option::is_none(&next_cost) || next_cost.unwrap() > pos_score + move_cost.up) {
|
||||
score_card[step.0][step.1] = Some(pos_score + move_cost.up);
|
||||
explore(grid, score_card, step, Cost { up: 1, down: MAX, left: 1001, right: 1001 });
|
||||
}
|
||||
}
|
||||
|
||||
// DOWN
|
||||
if let Some(step) = get_step(pos.0 as isize + 1, pos.1 as isize) {
|
||||
let next_cost = score_card[step.0][step.1];
|
||||
if move_cost.down != MAX && (Option::is_none(&next_cost) || next_cost.unwrap() > pos_score + move_cost.down) {
|
||||
score_card[step.0][step.1] = Some(pos_score + move_cost.down);
|
||||
explore(grid, score_card, step, Cost { up: MAX, down: 1, left: 1001, right: 1001 });
|
||||
}
|
||||
}
|
||||
|
||||
// LEFT
|
||||
if let Some(step) = get_step(pos.0 as isize, pos.1 as isize - 1) {
|
||||
let next_cost = score_card[step.0][step.1];
|
||||
if move_cost.left != MAX && (Option::is_none(&next_cost) || next_cost.unwrap() > pos_score + move_cost.left) {
|
||||
score_card[step.0][step.1] = Some(pos_score + move_cost.left);
|
||||
explore(grid, score_card, step, Cost { up: 1001, down: 1001, left: 1, right: MAX });
|
||||
}
|
||||
}
|
||||
|
||||
// RIGHT
|
||||
if let Some(step) = get_step(pos.0 as isize, pos.1 as isize + 1) {
|
||||
let next_cost = score_card[step.0][step.1];
|
||||
if move_cost.right != MAX && (Option::is_none(&next_cost) || next_cost.unwrap() > pos_score + move_cost.right) {
|
||||
score_card[step.0][step.1] = Some(pos_score + move_cost.right);
|
||||
explore(grid, score_card, step, Cost { up: 1001, down: 1001, left: MAX, right: 1 });
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -15,9 +119,16 @@ mod tests {
|
||||
#[test]
|
||||
fn test_part_one() {
|
||||
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
|
||||
assert_eq!(result, None);
|
||||
assert_eq!(result, Some(7036));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_one_2() {
|
||||
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
|
||||
assert_eq!(result, Some(11048));
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_part_two() {
|
||||
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
|
||||
|
||||
Reference in new issue
Block a user