use super::intcode;\r
use std::collections::HashSet;\r
\r
-#[derive(PartialEq, Eq, Copy, Clone)]\r
+#[derive(PartialEq, Eq, Copy, Clone, Debug)]\r
enum Direction { Up, Left, Down, Right }\r
\r
impl Direction {\r
}\r
}\r
\r
-#[derive(PartialEq, Eq, Copy, Clone)]\r
-struct MovementCommand { dir: Direction, steps: u32 }\r
+#[derive(PartialEq, Eq, Copy, Clone, Debug)]\r
+enum Movement { Left, Right }\r
+\r
+#[derive(PartialEq, Eq, Copy, Clone, Debug)]\r
+struct MovementCommand { mov: Movement, steps: u32 }\r
\r
pub struct RobotTrackingSystem {\r
output: Vec<i64>,\r
board: Vec<Vec<char>>,\r
start_position: (i32, i32),\r
start_dir: Direction,\r
+ crossings: Vec<(i32, i32)>,\r
+ dir_commands: Vec<MovementCommand>,\r
}\r
\r
impl RobotTrackingSystem {\r
board: Vec::<Vec<char>>::new(),\r
start_position: (0, 0),\r
start_dir: Direction::Up,\r
+ crossings: Vec::<(i32, i32)>::new(),\r
+ dir_commands: Vec::<MovementCommand>::new(),\r
}\r
}\r
\r
current_x += 1;\r
}\r
}\r
+\r
+ self.output.clear();\r
+ self.run_through();\r
+ }\r
+\r
+ // Run the path and find the crossings and define the movements.\r
+ fn run_through(&mut self) {\r
+ let (mut x, mut y) = self.start_position;\r
+ let mut dir = self.start_dir;\r
+ let mut visited_locations = HashSet::<(i32, i32)>::new();\r
+ visited_locations.insert((x, y));\r
+\r
+ let mut last_mov = Movement::Left;\r
+ let mut steps = 0;\r
+\r
+ 'main: loop {\r
+ let positions = [(Direction::Up, (x, y - 1)), (Direction::Left, (x - 1, y)), (Direction::Right, (x + 1, y)), (Direction::Down, (x, y + 1))];\r
+\r
+ let next_position = positions.iter().find(|(d, _)| *d == dir).unwrap().1;\r
+\r
+ // If the robot can continue straightforward.\r
+ if self.get(next_position.0, next_position.1) == Some('#') {\r
+ if !visited_locations.insert(next_position) {\r
+ self.crossings.push(next_position);\r
+ }\r
+ steps += 1;\r
+ x = next_position.0;\r
+ y = next_position.1;\r
+ continue;\r
+ }\r
+\r
+ if steps != 0 {\r
+ self.dir_commands.push(MovementCommand { mov: last_mov, steps });\r
+ steps = 0;\r
+ }\r
+\r
+ for (d, p) in &positions {\r
+ if self.get(p.0, p.1) == Some('#') && !visited_locations.contains(p) {\r
+\r
+ last_mov =\r
+ match (dir, *d) {\r
+ (Direction::Up, Direction::Right) | (Direction::Right, Direction::Down) | (Direction::Down, Direction::Left) | (Direction::Left, Direction::Up) => Movement::Right,\r
+ (Direction::Up, Direction::Left) | (Direction::Left, Direction::Down) | (Direction::Down, Direction::Right) | (Direction::Right, Direction::Up) => Movement::Left,\r
+ _ => panic!("Unable to find a movement from {:?} to {:?}", dir, *d)\r
+ };\r
+\r
+ visited_locations.insert(*p);\r
+ steps += 1;\r
+ dir = *d;\r
+ x = p.0;\r
+ y = p.1;\r
+ continue 'main;\r
+ }\r
+ }\r
+\r
+ break;\r
+ }\r
}\r
}\r
\r
// May block.\r
fn read(&mut self) -> i64 {\r
self.build_board_from_output();\r
- 42\r
+ 42 // TODO: part2.\r
}\r
\r
// Send to the output channel.\r
pub fn scaffold_intersections(code: &[i64]) -> i32 {\r
let mut rts = RobotTrackingSystem::new();\r
intcode::execute_op_code_with_custom_io(code, &mut rts);\r
-\r
- let (mut x, mut y) = rts.start_position;\r
- let mut dir = rts.start_dir;\r
- let mut visited_locations = HashSet::<(i32, i32)>::new();\r
- let mut crosses = Vec::<(i32, i32)>::new();\r
- visited_locations.insert((x, y));\r
-\r
- 'main: loop {\r
- let positions = [(Direction::Up, (x, y - 1)), (Direction::Left, (x - 1, y)), (Direction::Right, (x + 1, y)), (Direction::Down, (x, y + 1))];\r
-\r
- let next_position = positions.iter().find(|(d, _)| *d == dir).unwrap().1;\r
-\r
- // If the robot can continue straightforward.\r
- if rts.get(next_position.0, next_position.1) == Some('#') {\r
- if !visited_locations.insert(next_position) {\r
- crosses.push(next_position);\r
- }\r
- x = next_position.0;\r
- y = next_position.1;\r
- continue;\r
- }\r
-\r
- for (d, p) in &positions {\r
- if rts.get(p.0, p.1) == Some('#') && !visited_locations.contains(p) {\r
- visited_locations.insert(*p);\r
- dir = *d;\r
- x = p.0;\r
- y = p.1;\r
- continue 'main;\r
- }\r
- }\r
-\r
- break;\r
- }\r
-\r
- crosses.iter().fold(0, |sum, cross| sum + cross.0 * cross.1)\r
+ rts.crossings.iter().fold(0, |sum, crossing| sum + crossing.0 * crossing.1)\r
}\r
\r
pub fn part2(code: &[i64]) {\r
+ let mut rts = RobotTrackingSystem::new();\r
+ intcode::execute_op_code_with_custom_io(code, &mut rts);\r
\r
-}
\ No newline at end of file
+}\r