diff --git a/day_06/src/main.rs b/day_06/src/main.rs index 0a87bc1..58e42e0 100644 --- a/day_06/src/main.rs +++ b/day_06/src/main.rs @@ -108,6 +108,14 @@ impl Map { } } + pub fn width(&self) -> usize { + self.width + } + + pub fn height(&self) -> usize { + self.height + } + pub fn get_location(&self, x: isize, y: isize) -> Option { if x < 0 || x >= self.width as isize || y < 0 || y >= self.height as isize { return None; @@ -118,6 +126,19 @@ impl Map { pub fn get_position(&self, position: Position) -> Option { self.get_location(position.x(), position.y()) } + + pub fn add_obstruction(&mut self, position: Position) -> Option { + match self.get_position(position) { + Some(previously_obstructed) => { + self.data[position.y() as usize][position.x() as usize] = true; + Some(previously_obstructed) + } + None => { + // Outside bounds, so we do nothing and return None + None + } + } + } } impl Display for Map { @@ -169,7 +190,7 @@ fn load_map(input_file: &str) -> Result<(Map, Guard), Box> { Ok((Map::new(data), guard_position)) } -fn simulate_guard_path(mut guard_position: Guard, map: Map) -> (usize, bool) { +fn simulate_guard_path(mut guard_position: Guard, map: &Map) -> (usize, bool) { let mut visited_set: HashSet = HashSet::new(); visited_set.insert(*guard_position.position()); let mut guard_states_set: HashSet = HashSet::new(); @@ -211,10 +232,35 @@ fn main() -> Result<(), Box> { println!("{}", map); println!("{:?}", guard_position); - let (locations_visited, infinite_loop) = simulate_guard_path(guard_position, map); + let (locations_visited, infinite_loop) = simulate_guard_path(guard_position, &map); println!("infinite_loop={}", infinite_loop); println!("Number of locations visited: {}", locations_visited); + let mut count_looping_obstruction_locations = 0; + for y in 0..map.height() { + for x in 0..map.width() { + let position_to_obstruct = Position::new(x as isize, y as isize); + match map.get_position(position_to_obstruct) { + Some(currently_obstructed) => { + if position_to_obstruct != guard_position.position && !currently_obstructed { + let mut new_map = map.clone(); + new_map.add_obstruction(position_to_obstruct); + let (_, infinite_loop) = simulate_guard_path(guard_position, &new_map); + if infinite_loop { + count_looping_obstruction_locations += 1; + } + } + } + None => panic!("This should never happen!"), + } + } + } + + println!( + "Number places you can place obstruction to cause the guard to infinitely loop: {}", + count_looping_obstruction_locations + ); + Ok(()) }