From 9876a09b9069da056fabe75d81486601cb1ede4c Mon Sep 17 00:00:00 2001 From: Reiner Herrmann Date: Wed, 11 Dec 2019 23:17:02 +0100 Subject: day11 --- src/main.rs | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 135 insertions(+), 2 deletions(-) (limited to 'src') 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