From a369d5ee57f15e51b959d97b1a20e2c0cbe0904f Mon Sep 17 00:00:00 2001 From: alex <> Date: Fri, 6 Dec 2024 11:28:26 +0100 Subject: [PATCH] Day06 - part 2 --- src/day06.rs | 57 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/src/day06.rs b/src/day06.rs index 2056633..f6431f6 100644 --- a/src/day06.rs +++ b/src/day06.rs @@ -1,7 +1,8 @@ use std::error::Error; use std::path::Path; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; +#[derive(Clone)] struct Puzzle { map: HashMap<(isize, isize), char>, start: (isize, isize), @@ -41,7 +42,7 @@ impl Puzzle { let mut pos: (isize, isize) = self.start; let mut dir: (isize, isize) = (-1, 0); while self.map.contains_key(&pos) { - let mut c = self.map.get_mut(&pos).unwrap(); + let c = self.map.get_mut(&pos).unwrap(); if "^.".contains(*c) { *c = 'X'; } @@ -52,6 +53,39 @@ impl Puzzle { pos = (pos.0 + dir.0, pos.1 + dir.1); } } + + fn is_guard_loop(self: &Self) -> bool { + let mut turn_right: HashMap<(isize, isize), (isize, isize)> = HashMap::new(); + turn_right.insert((-1,0), (0,1)); + turn_right.insert((0,1), (1,0)); + turn_right.insert((1,0), (0,-1)); + turn_right.insert((0,-1), (-1,0)); + + // store the visited position (r,c) with a set of associated direction (dr,dc) + let mut visited: HashMap<(isize, isize), HashSet<(isize, isize)>> = HashMap::new(); + + let mut pos: (isize, isize) = self.start; + let mut dir: (isize, isize) = (-1, 0); + while self.map.contains_key(&pos) { + let c = self.map.get(&pos).unwrap(); + if "#O".contains(*c) { + pos = (pos.0 - dir.0, pos.1 - dir.1); + dir = *turn_right.get(&dir).unwrap(); + } + visited.entry(pos) + .and_modify(|dir_set| { dir_set.insert(dir); }) + .or_insert({ + let mut s = HashSet::new(); + s.insert(dir); + s + }); + pos = (pos.0 + dir.0, pos.1 + dir.1); + if visited.contains_key(&pos) && visited.get(&pos).unwrap().contains(&dir) { + return true; + } + } + false + } } pub fn run(input: &str) -> Result<(), Box> { @@ -86,7 +120,22 @@ fn run_part1(input: &str) -> Result> { fn run_part2(input: &str) -> Result> { println!("Running {} - part 2", get_day()); - Ok(0) + let mut puzzle = Puzzle::new(input); + + puzzle.guard_path(); + + let res: u32 = puzzle.map.clone().into_keys() + .filter(|k| *puzzle.map.get(k).unwrap() == 'X' && *k != puzzle.start) + .map(|k| { + let mut p = puzzle.clone(); + let c = p.map.get_mut(&k).unwrap(); + *c = 'O'; + p.is_guard_loop() + }) + .filter(|matches| *matches) + .count() as u32; + + Ok(res) } #[cfg(test)] @@ -112,6 +161,6 @@ mod tests { #[test] fn test_part2() { - assert_eq!(0, run_part2(TEXT_INPUT).unwrap()); + assert_eq!(6, run_part2(TEXT_INPUT).unwrap()); } } -- 2.39.5