From 77f1bc76895566a645f35e6ef9ef8ac3f783679b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gr=C3=A9gory=20Burri?= Date: Fri, 20 Dec 2019 09:52:38 +0100 Subject: [PATCH] Add movements (part2, WIP) --- src/day17.rs | 113 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 41 deletions(-) diff --git a/src/day17.rs b/src/day17.rs index 6998995..c64ed0e 100644 --- a/src/day17.rs +++ b/src/day17.rs @@ -1,7 +1,7 @@ use super::intcode; use std::collections::HashSet; -#[derive(PartialEq, Eq, Copy, Clone)] +#[derive(PartialEq, Eq, Copy, Clone, Debug)] enum Direction { Up, Left, Down, Right } impl Direction { @@ -16,14 +16,19 @@ impl Direction { } } -#[derive(PartialEq, Eq, Copy, Clone)] -struct MovementCommand { dir: Direction, steps: u32 } +#[derive(PartialEq, Eq, Copy, Clone, Debug)] +enum Movement { Left, Right } + +#[derive(PartialEq, Eq, Copy, Clone, Debug)] +struct MovementCommand { mov: Movement, steps: u32 } pub struct RobotTrackingSystem { output: Vec, board: Vec>, start_position: (i32, i32), start_dir: Direction, + crossings: Vec<(i32, i32)>, + dir_commands: Vec, } impl RobotTrackingSystem { @@ -33,6 +38,8 @@ impl RobotTrackingSystem { board: Vec::>::new(), start_position: (0, 0), start_dir: Direction::Up, + crossings: Vec::<(i32, i32)>::new(), + dir_commands: Vec::::new(), } } @@ -68,6 +75,63 @@ impl RobotTrackingSystem { current_x += 1; } } + + self.output.clear(); + self.run_through(); + } + + // Run the path and find the crossings and define the movements. + fn run_through(&mut self) { + let (mut x, mut y) = self.start_position; + let mut dir = self.start_dir; + let mut visited_locations = HashSet::<(i32, i32)>::new(); + visited_locations.insert((x, y)); + + let mut last_mov = Movement::Left; + let mut steps = 0; + + 'main: loop { + let positions = [(Direction::Up, (x, y - 1)), (Direction::Left, (x - 1, y)), (Direction::Right, (x + 1, y)), (Direction::Down, (x, y + 1))]; + + let next_position = positions.iter().find(|(d, _)| *d == dir).unwrap().1; + + // If the robot can continue straightforward. + if self.get(next_position.0, next_position.1) == Some('#') { + if !visited_locations.insert(next_position) { + self.crossings.push(next_position); + } + steps += 1; + x = next_position.0; + y = next_position.1; + continue; + } + + if steps != 0 { + self.dir_commands.push(MovementCommand { mov: last_mov, steps }); + steps = 0; + } + + for (d, p) in &positions { + if self.get(p.0, p.1) == Some('#') && !visited_locations.contains(p) { + + last_mov = + match (dir, *d) { + (Direction::Up, Direction::Right) | (Direction::Right, Direction::Down) | (Direction::Down, Direction::Left) | (Direction::Left, Direction::Up) => Movement::Right, + (Direction::Up, Direction::Left) | (Direction::Left, Direction::Down) | (Direction::Down, Direction::Right) | (Direction::Right, Direction::Up) => Movement::Left, + _ => panic!("Unable to find a movement from {:?} to {:?}", dir, *d) + }; + + visited_locations.insert(*p); + steps += 1; + dir = *d; + x = p.0; + y = p.1; + continue 'main; + } + } + + break; + } } } @@ -75,7 +139,7 @@ impl intcode::IO for RobotTrackingSystem { // May block. fn read(&mut self) -> i64 { self.build_board_from_output(); - 42 + 42 // TODO: part2. } // Send to the output channel. @@ -91,44 +155,11 @@ impl intcode::IO for RobotTrackingSystem { pub fn scaffold_intersections(code: &[i64]) -> i32 { let mut rts = RobotTrackingSystem::new(); intcode::execute_op_code_with_custom_io(code, &mut rts); - - let (mut x, mut y) = rts.start_position; - let mut dir = rts.start_dir; - let mut visited_locations = HashSet::<(i32, i32)>::new(); - let mut crosses = Vec::<(i32, i32)>::new(); - visited_locations.insert((x, y)); - - 'main: loop { - let positions = [(Direction::Up, (x, y - 1)), (Direction::Left, (x - 1, y)), (Direction::Right, (x + 1, y)), (Direction::Down, (x, y + 1))]; - - let next_position = positions.iter().find(|(d, _)| *d == dir).unwrap().1; - - // If the robot can continue straightforward. - if rts.get(next_position.0, next_position.1) == Some('#') { - if !visited_locations.insert(next_position) { - crosses.push(next_position); - } - x = next_position.0; - y = next_position.1; - continue; - } - - for (d, p) in &positions { - if rts.get(p.0, p.1) == Some('#') && !visited_locations.contains(p) { - visited_locations.insert(*p); - dir = *d; - x = p.0; - y = p.1; - continue 'main; - } - } - - break; - } - - crosses.iter().fold(0, |sum, cross| sum + cross.0 * cross.1) + rts.crossings.iter().fold(0, |sum, crossing| sum + crossing.0 * crossing.1) } pub fn part2(code: &[i64]) { + let mut rts = RobotTrackingSystem::new(); + intcode::execute_op_code_with_custom_io(code, &mut rts); -} \ No newline at end of file +} -- 2.45.2