From 9876a09b9069da056fabe75d81486601cb1ede4c Mon Sep 17 00:00:00 2001 From: Reiner Herrmann Date: Wed, 11 Dec 2019 23:17:02 +0100 Subject: day11 --- input11 | 1 + src/main.rs | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 input11 diff --git a/input11 b/input11 new file mode 100644 index 0000000..7c041fb --- /dev/null +++ b/input11 @@ -0,0 +1 @@ +3,8,1005,8,326,1106,0,11,0,0,0,104,1,104,0,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,1,10,4,10,1001,8,0,29,2,1003,17,10,1006,0,22,2,106,5,10,1006,0,87,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,1,10,4,10,1001,8,0,65,2,7,20,10,2,9,17,10,2,6,16,10,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,0,10,4,10,101,0,8,99,1006,0,69,1006,0,40,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,1,10,4,10,101,0,8,127,1006,0,51,2,102,17,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,1,8,10,4,10,1002,8,1,155,1006,0,42,3,8,1002,8,-1,10,101,1,10,10,4,10,108,0,8,10,4,10,101,0,8,180,1,106,4,10,2,1103,0,10,1006,0,14,3,8,102,-1,8,10,1001,10,1,10,4,10,108,0,8,10,4,10,1001,8,0,213,1,1009,0,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,0,8,10,4,10,1002,8,1,239,1006,0,5,2,108,5,10,2,1104,7,10,3,8,102,-1,8,10,101,1,10,10,4,10,108,0,8,10,4,10,102,1,8,272,2,1104,12,10,1,1109,10,10,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,102,1,8,302,1006,0,35,101,1,9,9,1007,9,1095,10,1005,10,15,99,109,648,104,0,104,1,21102,937268449940,1,1,21102,1,343,0,1105,1,447,21101,387365315480,0,1,21102,1,354,0,1105,1,447,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,21101,0,29220891795,1,21102,1,401,0,1106,0,447,21101,0,248075283623,1,21102,412,1,0,1105,1,447,3,10,104,0,104,0,3,10,104,0,104,0,21101,0,984353760012,1,21102,1,435,0,1105,1,447,21102,1,718078227200,1,21102,1,446,0,1105,1,447,99,109,2,21202,-1,1,1,21102,40,1,2,21101,0,478,3,21101,468,0,0,1106,0,511,109,-2,2106,0,0,0,1,0,0,1,109,2,3,10,204,-1,1001,473,474,489,4,0,1001,473,1,473,108,4,473,10,1006,10,505,1102,1,0,473,109,-2,2105,1,0,0,109,4,1202,-1,1,510,1207,-3,0,10,1006,10,528,21102,1,0,-3,22102,1,-3,1,22101,0,-2,2,21101,0,1,3,21102,1,547,0,1105,1,552,109,-4,2105,1,0,109,5,1207,-3,1,10,1006,10,575,2207,-4,-2,10,1006,10,575,21202,-4,1,-4,1105,1,643,21202,-4,1,1,21201,-3,-1,2,21202,-2,2,3,21102,1,594,0,1106,0,552,22102,1,1,-4,21101,1,0,-1,2207,-4,-2,10,1006,10,613,21101,0,0,-1,22202,-2,-1,-2,2107,0,-3,10,1006,10,635,22101,0,-1,1,21101,0,635,0,106,0,510,21202,-2,-1,-2,22201,-4,-2,-4,109,-5,2105,1,0 diff --git a/src/main.rs b/src/main.rs index 4dcf205..e482946 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,12 +6,19 @@ use std::cmp::Ordering; use std::collections::VecDeque; use std::collections::HashMap; -#[derive(Eq, PartialEq, Clone, Copy, Debug)] +#[derive(Eq, PartialEq, Clone, Copy, Debug, Hash)] struct Point { x : i32, y : i32, } +enum Direction { + UP = 0, + RIGHT = 1, + DOWN = 2, + LEFT = 3, +} + struct Line { p1 : Point, p2 : Point, @@ -79,6 +86,15 @@ impl Point { y: to.y - self.y, } } + + fn move_in_direction(&mut self, direction: &Direction) { + match direction { + Direction::UP => self.y += 1, + Direction::RIGHT => self.x += 1, + Direction::DOWN => self.y -= 1, + Direction::LEFT => self.x -= 1, + }; + } } impl Line { @@ -172,6 +188,7 @@ enum ProgramState { RUNNING, HALTED, SUSPENDED, + NEEDINPUT, } struct IntComputer { @@ -260,6 +277,9 @@ impl IntComputer { self.ip += 4; } 3 => { /* read stdin */ + if self.input.is_empty() { + return ProgramState::NEEDINPUT; + } let dst = self.mem[self.ip+1] as isize; let input = self.input.pop_front().expect("not enough input available"); self.write_mem(dst, input, mode); @@ -800,8 +820,121 @@ fn day10() { println!("10b: {}", vaporized.x * 100 + vaporized.y); } +struct RobotDirection { + direction: Direction, +} + +impl RobotDirection { + fn rotate(&mut self, direction: isize) { + self.direction = match direction { + 0 => { + match &self.direction { + Direction::UP => Direction::LEFT, + Direction::LEFT => Direction::DOWN, + Direction::DOWN => Direction::RIGHT, + Direction::RIGHT => Direction::UP, + } + } + 1 => { + match &self.direction { + Direction::UP => Direction::RIGHT, + Direction::RIGHT => Direction::DOWN, + Direction::DOWN => Direction::LEFT, + Direction::LEFT => Direction::UP, + } + } + _ => panic!("invalid direction") + } + } +} + +fn hull_paint(program: &[isize], starting_color: isize) -> HashMap { + let mut computer = IntComputer::new(program); + computer.suspend_on_output = true; + + let mut hull = HashMap::new(); + let mut pos = Point { x: 0, y: 0 }; + let mut direction = RobotDirection { direction: Direction::UP }; + let mut new_color = None; + let mut rotation = None; + hull.insert(pos, starting_color); + loop { + match computer.run_program() { + ProgramState::SUSPENDED => { + let output = computer.output.pop_front().unwrap(); + if new_color.is_none() { + new_color = Some(output); + } else if rotation.is_none() { + rotation = Some(output); + } else { + panic!("unexpected state"); + } + } + ProgramState::NEEDINPUT => { + computer.input.push_back(*hull.entry(pos).or_insert(0)); + continue; + } + ProgramState::HALTED => break, + _ => {} + } + if new_color.is_some() && rotation.is_some() { + hull.insert(pos, new_color.unwrap()); + direction.rotate(rotation.unwrap()); + pos.move_in_direction(&direction.direction); + new_color = None; + rotation = None; + } + } + hull +} + +fn day11() { + let input = read_file("input11"); + let input = input.trim_end(); + let program : Vec = input.split(',') + .map(|x| x.parse::().unwrap()) + .collect(); + + let hull = hull_paint(&program, 0); + println!("11a: {}", hull.len()); + + let hull = hull_paint(&program, 1); + let mut min_x = i32::max_value(); + let mut min_y = i32::max_value(); + let mut max_x = i32::min_value(); + let mut max_y = i32::min_value(); + for (pos, _) in &hull { + min_x = cmp::min(min_x, pos.x); + min_y = cmp::min(min_y, pos.y); + max_x = cmp::max(max_x, pos.x); + max_y = cmp::max(max_y, pos.y); + } + let mut hull_vec = Vec::new(); + for _ in 0..=(max_y - min_y) { + let mut row = Vec::new(); + row.resize((max_x - min_x + 1) as usize, 0); + hull_vec.push(row); + } + for (pos, color) in &hull { + hull_vec[(pos.y - min_y) as usize][(pos.x - min_x) as usize] = *color; + } + hull_vec.reverse(); + + println!("11b:"); + for row in hull_vec { + for color in row { + match color { + 0 => print!("."), + 1 => print!("#"), + _ => panic!("invalid color") + } + } + println!(); + } +} + fn main() { - day10(); + day11(); } #[cfg(test)] -- cgit v1.2.3