From fd3629acfda9bc72ac19b4f006484058998aea27 Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 16 Dec 2024 12:17:55 +0100 Subject: [PATCH] day 16 part 1 day 16 part 1 --- src/day16.rs | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + src/main.rs | 1 + 3 files changed, 123 insertions(+) create mode 100644 src/day16.rs diff --git a/src/day16.rs b/src/day16.rs new file mode 100644 index 0000000..8082113 --- /dev/null +++ b/src/day16.rs @@ -0,0 +1,121 @@ +use std::{ + collections::{BinaryHeap, HashMap}, + fs::read_to_string, +}; + +use crate::utils::grid::{Coord, Grid}; + +pub fn day_main() { + let input = read_to_string("input/day16.txt").unwrap(); + let input = input.trim(); + println!(" part1: {}", part1(input)); + println!(" part2: {}", part2(input)); +} + +type RiddleResult = usize; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum Dir { + N, + E, + S, + W, +} + +impl Dir { + fn nexts(&self) -> [Self; 2] { + match self { + Dir::N | Dir::S => [Dir::W, Dir::E], + Dir::E | Dir::W => [Dir::S, Dir::N], + } + } +} + +struct Step(Coord, Dir, usize); + +impl Ord for Step { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + other.2.cmp(&self.2) + } +} +impl PartialOrd for Step { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} +impl PartialEq for Step { + fn eq(&self, other: &Self) -> bool { + other.2.eq(&self.2) + } +} +impl Eq for Step {} + +fn part1(input: &str) -> RiddleResult { + use Dir::*; + let maze = Grid::parse(input); + let start = maze.entries().find(|(_p, c)| **c == 'S').unwrap().0; + let end = maze.entries().find(|(_p, c)| **c == 'E').unwrap().0; + let mut visited = HashMap::<(Coord, Dir), usize>::new(); + let mut stack: BinaryHeap = BinaryHeap::new(); + stack.push(Step(start, E, 0)); + while let Some(Step(np, nd, cost)) = stack.pop() { + if visited.contains_key(&(np, nd)) { + continue; + } + visited.insert((np, nd), cost); + if np == end { + return cost; + } + for d in nd.nexts() { + if !visited.contains_key(&(np, d)) { + stack.push(Step(np, d, cost + 1000)); + } + } + let forward = match nd { + N => (np.0, np.1 - 1), + E => (np.0 + 1, np.1), + S => (np.0, np.1 + 1), + W => (np.0 - 1, np.1), + }; + if maze[forward] != '#' && !visited.contains_key(&(forward, nd)) { + stack.push(Step(forward, nd, cost + 1)); + } + } + panic!("no path found") +} + +fn part2(_input: &str) -> RiddleResult { + 0 +} + +#[cfg(test)] +mod test { + use super::{part1, part2}; + + const TEST_INPUT: &str = r"############### +#.......#....E# +#.#.###.#.###.# +#.....#.#...#.# +#.###.#####.#.# +#.#.#.......#.# +#.#.#####.###.# +#...........#.# +###.#.#####.#.# +#...#.....#.#.# +#.#.#.###.#.#.# +#.....#...#.#.# +#.###.#.#.#.#.# +#S..#.....#...# +############### +"; + + #[test] + fn test1() { + assert_eq!(part1(TEST_INPUT), 7036); + } + + #[test] + fn test2() { + assert_eq!(part2(TEST_INPUT), 0); + } +} diff --git a/src/lib.rs b/src/lib.rs index 594a95f..9d8434a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,5 +13,6 @@ pub mod day12; pub mod day13; pub mod day14; pub mod day15; +pub mod day16; // PLACEHOLDER pub mod utils; diff --git a/src/main.rs b/src/main.rs index 00b7b58..4bb00b6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,7 @@ fn main() { (13, day13::day_main), (14, day14::day_main), (15, day15::day_main), + (16, day16::day_main), // PLACEHOLDER ]); let day: Option = args().nth(1).and_then(|a| a.parse().ok());