day 6 complete

master
Joey Pollack 1 year ago
parent ab038c8d6d
commit 7f4dd970d5

@ -298,7 +298,7 @@ impl Rule
return true; return true;
} }
fn make_valid(self: &Rule, update: &mut Vec<i32>, enable_debug_output: bool) fn make_valid(self: &Rule, update: &mut Vec<i32>, _enable_debug_output: bool)
{ {
let mut first_idx = 0; let mut first_idx = 0;
let mut second_idx = 0; let mut second_idx = 0;

@ -8,6 +8,7 @@
* @brief Advent of Code 2024 day 6 problems * @brief Advent of Code 2024 day 6 problems
******************************************************************************/ ******************************************************************************/
use nalgebra_glm::I32Vec2;
use ::solver_base::solver_base::{Solver, DataSet, RunMode}; use ::solver_base::solver_base::{Solver, DataSet, RunMode};
use utils::utils; use utils::utils;
@ -20,7 +21,9 @@ pub struct Day6
do_debug_prints: bool, do_debug_prints: bool,
map: Map, map: Map,
guard_history: Vec<Vec<bool>>, guard_heatmap: Vec<Vec<bool>>,
guard_position_history: Vec<I32Vec2>,
step_iterations: i32,
pub final_result: i32, pub final_result: i32,
} }
@ -32,16 +35,23 @@ impl Day6
pub fn new() -> Day6 pub fn new() -> Day6
{ {
Day6 { data_set: DataSet::Test, run_mode: RunMode::FirstCase, do_debug_prints: false, 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 fn solve_first_case(self: &mut Self) -> String
{ {
self.step_iterations = 0;
while self.map.guard_is_on_map() 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.map.step_guard();
self.step_iterations += 1;
} }
if self.do_debug_prints if self.do_debug_prints
@ -52,7 +62,7 @@ impl Day6
let mut num_locations = 0; let mut num_locations = 0;
for row in &self.guard_history for row in &self.guard_heatmap
{ {
for b in row for b in row
{ {
@ -69,10 +79,66 @@ impl Day6
fn solve_second_case(self: &mut Self) -> 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<I32Vec2> = 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() self.final_result.to_string()
} }
} }
//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| //|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@ -109,7 +175,7 @@ impl Solver for Day6
self.map.print(); 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 fn solve(self: &mut Self) -> String

@ -31,6 +31,7 @@ pub enum Direction
pub struct Map pub struct Map
{ {
map: Vec<Vec<MapCell>>, map: Vec<Vec<MapCell>>,
guard_start_pos: I32Vec2,
guard_direction: Direction, guard_direction: Direction,
guard_pos: nalgebra_glm::I32Vec2, guard_pos: nalgebra_glm::I32Vec2,
} }
@ -39,7 +40,7 @@ impl Map
{ {
pub fn new() -> 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 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) pub fn print(self: &Map)
@ -125,6 +126,11 @@ impl Map
self.map.len() as i32 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: /// Step Rules:
/// ///
/// If there is something directly in front of you, turn right 90 degrees. /// If there is something directly in front of you, turn right 90 degrees.
@ -170,8 +176,8 @@ impl Map
{ {
pos.x >= 0 && pos.x >= 0 &&
pos.y >= 0 && pos.y >= 0 &&
(pos.x as usize) < self.map[0].len() && (pos.x as usize) < self.map.len() &&
(pos.y as usize) < self.map.len() (pos.y as usize) < self.map[0].len()
} }
pub fn guard_position(self: &Map) -> I32Vec2 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;
}
}
}
}
} }

@ -89,10 +89,10 @@ fn main()
let day6_result = day_6.solve(); let day6_result = day_6.solve();
println!("Day 6 Part 1 Final Result: {}", day6_result); println!("Day 6 Part 1 Final Result: {}", day6_result);
// let mut day_6 = Day6::new(); let mut day_6 = Day6::new();
// day_6.init(DataSet::Full, RunMode::SecondCase, false); day_6.init(DataSet::Full, RunMode::SecondCase, false);
// let day6_result = day_6.solve(); let day6_result = day_6.solve();
// println!("Day 6 Part 2 Final Result: {}", day6_result); println!("Day 6 Part 2 Final Result: {}", day6_result);
println!("-------------------------"); println!("-------------------------");

Loading…
Cancel
Save