From 745d4a8029aba75dfda23884eb78a5de03d48420 Mon Sep 17 00:00:00 2001 From: jazzpi Date: Sat, 24 Dec 2022 18:45:53 +0100 Subject: [PATCH] Day 24, part 2 --- src/bin/d24p1.rs | 2 +- src/bin/d24p2.rs | 19 +++++++++++++++++++ src/day24.rs | 29 ++++++++++++++++++++--------- 3 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 src/bin/d24p2.rs diff --git a/src/bin/d24p1.rs b/src/bin/d24p1.rs index 3554bb8..aba17b1 100644 --- a/src/bin/d24p1.rs +++ b/src/bin/d24p1.rs @@ -8,6 +8,6 @@ pub fn main() { day24::print_map(&map, &start); - let rounds = day24::find_path(&map, &start, &target); + let (rounds, _) = day24::find_path(&map, &start, &target); println!("Goal is reachable in {} min", rounds); } diff --git a/src/bin/d24p2.rs b/src/bin/d24p2.rs new file mode 100644 index 0000000..fafa3a4 --- /dev/null +++ b/src/bin/d24p2.rs @@ -0,0 +1,19 @@ +use aoc22::{ + day24::{self}, + util, +}; + +pub fn main() { + let (map, start, target) = day24::parse_map(&util::parse_input()); + + day24::print_map(&map, &start); + + let (rounds_1, map_1) = day24::find_path(&map, &start, &target); + println!("Goal is reachable in {} min", rounds_1); + let (rounds_2, map_2) = day24::find_path(&map_1, &target, &start); + println!("Start is reachable in {} min", rounds_2); + let (rounds_3, _) = day24::find_path(&map_2, &start, &target); + println!("Goal is reachable in {} min", rounds_2); + + println!("Total time taken is {} min", rounds_1 + rounds_2 + rounds_3); +} diff --git a/src/day24.rs b/src/day24.rs index e83c332..0ef0fcf 100644 --- a/src/day24.rs +++ b/src/day24.rs @@ -139,7 +139,15 @@ pub fn next_map(map: &Vec>) -> Vec> { } /// Returns length of the shortest path -pub fn find_path(initial: &Vec>, start: &Coord, target: &Coord) -> usize { +pub fn find_path( + initial: &Vec>, + start: &Coord, + target: &Coord, +) -> (usize, Vec>) { + let height = initial.len(); + assert!(height > 0); + let width = initial[0].len(); + let mut map = initial.clone(); let mut to_check = HashSet::new(); to_check.insert(*start); @@ -151,20 +159,23 @@ pub fn find_path(initial: &Vec>, start: &Coord, target: &Coord) -> usi let mut check_next = HashSet::new(); for pos in to_check { - let mut reachable = vec![ - pos, - (pos.0 + 1, pos.1), - (pos.0, pos.1 + 1), - (pos.0, pos.1 - 1), - ]; - // This would underflow in the first round + let mut reachable = vec![pos]; if pos.0 != 0 { reachable.push((pos.0 - 1, pos.1)); } + if pos.0 != height - 1 { + reachable.push((pos.0 + 1, pos.1)); + } + if pos.1 != 0 { + reachable.push((pos.0, pos.1 - 1)); + } + if pos.1 != width - 1 { + reachable.push((pos.0, pos.1 + 1)); + } for p in reachable { if p == *target { - return rounds; + return (rounds, map); } if matches!(map[p.0][p.1], Tile::Empty) { check_next.insert(p);