From 5a04eddcef2334f0583075153d5423c60fc77ce4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gr=C3=A9gory=20Burri?= Date: Wed, 18 Dec 2019 12:54:18 +0100 Subject: [PATCH] Preparing for day 17 part 2... --- src/day15.rs | 2 +- src/day16.rs | 1 + src/day17.rs | 105 ++++++++++++++++++++++++++++++++++--------------- src/intcode.rs | 3 ++ src/main.rs | 4 +- 5 files changed, 81 insertions(+), 34 deletions(-) diff --git a/src/day15.rs b/src/day15.rs index 86073b4..e6286e2 100644 --- a/src/day15.rs +++ b/src/day15.rs @@ -21,7 +21,7 @@ pub struct DroidTrackingSystem { } impl DroidTrackingSystem { - fn new() -> DroidTrackingSystem { + fn new() -> Self { DroidTrackingSystem { board: HashMap::from_iter(vec![((0, 0), LocationState::Visited)].into_iter()), current_path: vec![(0, 0)], diff --git a/src/day16.rs b/src/day16.rs index 2112c0e..931ff5b 100644 --- a/src/day16.rs +++ b/src/day16.rs @@ -61,6 +61,7 @@ fn dft(scale: usize, csum: &[i32]) -> i32 { out.abs() % 10 } +#[allow(dead_code)] pub fn part2(input: &[i32]) -> Vec { let size = input.len(); let mut input = Vec::from_iter(input.iter().cycle().take(size * 10_000).copied()); diff --git a/src/day17.rs b/src/day17.rs index 15bd825..8907e78 100644 --- a/src/day17.rs +++ b/src/day17.rs @@ -1,42 +1,80 @@ use super::intcode; use std::collections::HashSet; -pub fn scaffold_intersections(code: &[i64]) -> i32 { - let output = intcode::execute_op_code(code, &[]); - let mut board = Vec::>::new(); - let mut current_line = Vec::::new(); - - let (mut x, mut y) = (0i32, 0i32); - let mut dir = '^'; - - let mut current_x = 0; - for c in output { - if c == 10 { - board.push(current_line); - current_line = Vec::::new(); - current_x = 0; - //println!(""); - } else { - let c = (c as u8) as char; - if let '^' | '<' | 'v' | '>' = c { - x = current_x; - y = board.len() as i32; - dir = c; - } - //print!("{}", c); - current_line.push(c); - current_x += 1; +pub struct RobotTrackingSystem { + output: Vec, + board: Vec>, + start_position: (i32, i32), + start_dir: char, +} + +impl RobotTrackingSystem { + fn new() -> Self { + RobotTrackingSystem { + output: Vec::new(), + board: Vec::>::new(), + start_position: (0, 0), + start_dir: '^', } } - let get = |x: i32, y: i32| -> Option { - if x < board[0].len() as i32 && x >= 0 && y < board.len() as i32 && y >= 0 { - Some(board[y as usize][x as usize]) + fn get(&self, x: i32, y: i32) -> Option { + if x < self.board[0].len() as i32 && x >= 0 && y < self.board.len() as i32 && y >= 0 { + Some(self.board[y as usize][x as usize]) } else { None } - }; + } + + fn build_board_from_output(&mut self) { + // If the board has already been read. + if !self.board.is_empty() { + return; + } + + let mut current_line = Vec::::new(); + let mut current_x = 0; + for c in self.output.iter() { + if *c == 10 { + self.board.push(current_line); + current_line = Vec::::new(); + current_x = 0; + } else { + let c = (*c as u8) as char; + if let '^' | '<' | 'v' | '>' = c { + self.start_position = (current_x, self.board.len() as i32); + self.start_dir = c; + } + current_line.push(c); + current_x += 1; + } + } + } +} +impl intcode::IO for RobotTrackingSystem { + // May block. + fn read(&mut self) -> i64 { + self.build_board_from_output(); + 42 + } + + // Send to the output channel. + fn write(&mut self, value: i64) { + self.output.push(value); + } + + fn finished(&mut self) { + self.build_board_from_output(); + } +} + +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)); @@ -45,10 +83,9 @@ pub fn scaffold_intersections(code: &[i64]) -> i32 { let positions = [('^', (x, y - 1)), ('<', (x - 1, y)), ('>', (x + 1, y)), ('v', (x, y + 1))]; let next_position = positions.iter().find(|(d, _)| *d == dir).unwrap().1; - //match dir { '^' => positions[0], '<' => positions[1], '>' => positions[2], 'v' | _ => positions[3] }; // If the robot can continue straightforward. - if get(next_position.0, next_position.1) == Some('#') { + if rts.get(next_position.0, next_position.1) == Some('#') { if !visited_locations.insert(next_position) { crosses.push(next_position); } @@ -58,7 +95,7 @@ pub fn scaffold_intersections(code: &[i64]) -> i32 { } for (d, p) in &positions { - if get(p.0, p.1) == Some('#') && !visited_locations.contains(p) { + if rts.get(p.0, p.1) == Some('#') && !visited_locations.contains(p) { visited_locations.insert(*p); dir = *d; x = p.0; @@ -71,4 +108,8 @@ pub fn scaffold_intersections(code: &[i64]) -> i32 { } crosses.iter().fold(0, |sum, cross| sum + cross.0 * cross.1) +} + +pub fn part2(code: &[i64]) { + } \ No newline at end of file diff --git a/src/intcode.rs b/src/intcode.rs index c2a28df..ff3e34b 100644 --- a/src/intcode.rs +++ b/src/intcode.rs @@ -9,6 +9,7 @@ pub trait IO { fn read(&mut self) -> i64; fn write(&mut self, value: i64); fn halt(&self) -> bool { false } + fn finished(&mut self) { } } struct Buffer { @@ -157,6 +158,8 @@ pub fn execute_op_code_with_custom_io(code: &[i64], io: &mut dyn IO) { _ => panic!("Unknown code: {}", code[cursor]) } } + + io.finished(); } #[cfg(test)] diff --git a/src/main.rs b/src/main.rs index 4788102..c66dfc9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -128,8 +128,10 @@ fn day16() -> String { } fn day17() -> String { - let code = common::read_list_of_numbers("data/day17.input", ","); + let mut code = common::read_list_of_numbers("data/day17.input", ","); let n = day17::scaffold_intersections(&code); + code[0] = 2; + day17::part2(&code); format!("part1: {}, part2: {}", n, "") } -- 2.45.2