diff --git a/crates/day_5/src/day_5.rs b/crates/day_5/src/day_5.rs index 68fa2c2..36db0dc 100644 --- a/crates/day_5/src/day_5.rs +++ b/crates/day_5/src/day_5.rs @@ -298,7 +298,7 @@ impl Rule return true; } - fn make_valid(self: &Rule, update: &mut Vec, enable_debug_output: bool) + fn make_valid(self: &Rule, update: &mut Vec, _enable_debug_output: bool) { let mut first_idx = 0; let mut second_idx = 0; diff --git a/crates/day_6/data/day6_input b/crates/day_6/data/day6_input index de833c2..df90ff1 100644 --- a/crates/day_6/data/day6_input +++ b/crates/day_6/data/day6_input @@ -127,4 +127,4 @@ ..........................#........#.........................................................#......#........................##... .................#....#............#...#...........................#....#....#....#...#........................................... .............#.......................................................#.........#.................................................. -....#.................................#...............#.....#....#......##..............#.......................#........#........ +....#.................................#...............#.....#....#......##..............#.......................#........#........ \ No newline at end of file diff --git a/crates/day_6/src/day_6.rs b/crates/day_6/src/day_6.rs index ee6799f..4181883 100644 --- a/crates/day_6/src/day_6.rs +++ b/crates/day_6/src/day_6.rs @@ -8,6 +8,7 @@ * @brief Advent of Code 2024 day 6 problems ******************************************************************************/ +use nalgebra_glm::I32Vec2; use ::solver_base::solver_base::{Solver, DataSet, RunMode}; use utils::utils; @@ -20,7 +21,9 @@ pub struct Day6 do_debug_prints: bool, map: Map, - guard_history: Vec>, + guard_heatmap: Vec>, + guard_position_history: Vec, + step_iterations: i32, pub final_result: i32, } @@ -32,16 +35,23 @@ impl Day6 pub fn new() -> Day6 { Day6 { data_set: DataSet::Test, run_mode: RunMode::FirstCase, do_debug_prints: false, - map: Map::new(), guard_history: vec![], final_result: 0 } + map: Map::new(), guard_heatmap: vec![], guard_position_history: vec![], step_iterations: 0, final_result: 0 } } fn solve_first_case(self: &mut Self) -> String { + self.step_iterations = 0; while self.map.guard_is_on_map() { + let pos = I32Vec2::new(self.map.guard_position().x, self.map.guard_position().y); + if !self.guard_position_history.contains(&pos) + { + self.guard_position_history.push(pos); + } - self.guard_history[self.map.guard_position().x as usize][self.map.guard_position().y as usize] = true; + self.guard_heatmap[self.map.guard_position().x as usize][self.map.guard_position().y as usize] = true; self.map.step_guard(); + self.step_iterations += 1; } if self.do_debug_prints @@ -52,7 +62,7 @@ impl Day6 let mut num_locations = 0; - for row in &self.guard_history + for row in &self.guard_heatmap { for b in row { @@ -66,13 +76,69 @@ impl Day6 self.final_result = num_locations; self.final_result.to_string() } - + fn solve_second_case(self: &mut Self) -> String { + // Need the normal path the guard will take without modifying the map first so just.... + self.solve_first_case(); + println!("Step Iterations: {}", self.step_iterations); - + // Should only need to check the spots the guard visits normally for potential locations for new blockers + // So the self.guard_history vector should now contain all potential locations for new blockers. + + // first attempt: I guess just try brute force with upper-limit for step iterations to guess that it's stuck + + // The normal path is 5532 step iterations so maybe 10,000 is enough to determine it is stuck? + let stuck_limit = 10000; // 100,000 to double check -- 10,000 works! 1995 is the correct answer + let mut found_locations: Vec = vec![]; + + println!("Positions to test: {}", self.guard_position_history.len()); + println!("0%"); + + for (i, pos) in self.guard_position_history.iter().enumerate() + { + + if i == self.guard_position_history.len() / 4 + { + println!("25%"); + } + + if i == self.guard_position_history.len() / 2 + { + println!("50%"); + } + + self.map.reset_guard(); + self.map.clear_visited(); + let mut iterations = 0; + let mut possibly_stuck = false; + + let mut map_clone = self.map.clone(); + + map_clone.add_blocker_at(&pos); + + while map_clone.guard_is_on_map() + { + map_clone.step_guard(); + iterations += 1; + + if iterations >= stuck_limit + { + possibly_stuck = true; + break; + } + } + + if possibly_stuck + { + found_locations.push(*pos); + } + } + + self.final_result = found_locations.len() as i32; self.final_result.to_string() } + } //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| @@ -109,7 +175,7 @@ impl Solver for Day6 self.map.print(); } - self.guard_history = vec![vec![false; self.map.width() as usize]; self.map.height() as usize]; + self.guard_heatmap = vec![vec![false; self.map.width() as usize]; self.map.height() as usize]; } fn solve(self: &mut Self) -> String diff --git a/crates/day_6/src/map.rs b/crates/day_6/src/map.rs index 22b8cf4..d958d83 100644 --- a/crates/day_6/src/map.rs +++ b/crates/day_6/src/map.rs @@ -31,6 +31,7 @@ pub enum Direction pub struct Map { map: Vec>, + guard_start_pos: I32Vec2, guard_direction: Direction, guard_pos: nalgebra_glm::I32Vec2, } @@ -39,7 +40,7 @@ impl Map { pub fn new() -> Map { - Map { map: vec![], guard_direction: Direction::North, guard_pos: I32Vec2::new(0, 0) } + Map { map: vec![], guard_start_pos: I32Vec2::new(0, 0), guard_direction: Direction::North, guard_pos: I32Vec2::new(0, 0) } } pub fn parse(data: &str) -> Map @@ -72,7 +73,7 @@ impl Map } } - Map { map, guard_direction: Direction::North, guard_pos } + Map { map, guard_start_pos: guard_pos, guard_direction: Direction::North, guard_pos } } pub fn print(self: &Map) @@ -125,6 +126,11 @@ impl Map self.map.len() as i32 } + pub fn add_blocker_at(self: &mut Map, at: &I32Vec2) + { + self.map[at.x as usize][at.y as usize] = MapCell::Block; + } + /// Step Rules: /// /// If there is something directly in front of you, turn right 90 degrees. @@ -170,8 +176,8 @@ impl Map { pos.x >= 0 && pos.y >= 0 && - (pos.x as usize) < self.map[0].len() && - (pos.y as usize) < self.map.len() + (pos.x as usize) < self.map.len() && + (pos.y as usize) < self.map[0].len() } pub fn guard_position(self: &Map) -> I32Vec2 @@ -202,4 +208,24 @@ impl Map }; } + pub fn reset_guard(self: &mut Map) + { + self.guard_pos = self.guard_start_pos; + self.guard_direction = Direction::North; + } + + pub fn clear_visited(self: &mut Map) + { + for row in &mut self.map + { + for c in row + { + if *c == MapCell::Visited + { + *c = MapCell::Space; + } + } + } + } + } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 04a0cf9..6dad444 100644 --- a/src/main.rs +++ b/src/main.rs @@ -89,10 +89,10 @@ fn main() let day6_result = day_6.solve(); println!("Day 6 Part 1 Final Result: {}", day6_result); - // let mut day_6 = Day6::new(); - // day_6.init(DataSet::Full, RunMode::SecondCase, false); - // let day6_result = day_6.solve(); - // println!("Day 6 Part 2 Final Result: {}", day6_result); + let mut day_6 = Day6::new(); + day_6.init(DataSet::Full, RunMode::SecondCase, false); + let day6_result = day_6.solve(); + println!("Day 6 Part 2 Final Result: {}", day6_result); println!("-------------------------");