From 0840e8e642d66869b4950c16d5578a1a3c4460a9 Mon Sep 17 00:00:00 2001 From: Adam Wick Date: Wed, 18 Dec 2019 21:57:48 -0800 Subject: [PATCH] Day 11! --- Cargo.toml | 1 + inputs/day11 | 1 + src/image.rs | 4 +- src/machine.rs | 2 +- src/main.rs | 1 + src/robot.rs | 152 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 inputs/day11 create mode 100644 src/robot.rs diff --git a/Cargo.toml b/Cargo.toml index 9f303a5..0af5166 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,4 @@ edition = "2018" [dependencies] bytecount = "^0.6.0" clap = "^2.33.0" +image = "^0.22.0" \ No newline at end of file diff --git a/inputs/day11 b/inputs/day11 new file mode 100644 index 0000000..b1a2f81 --- /dev/null +++ b/inputs/day11 @@ -0,0 +1 @@ +3,8,1005,8,332,1106,0,11,0,0,0,104,1,104,0,3,8,102,-1,8,10,101,1,10,10,4,10,108,1,8,10,4,10,101,0,8,28,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,1,10,4,10,101,0,8,51,1,1103,5,10,1,1104,9,10,2,1003,0,10,1,5,16,10,3,8,102,-1,8,10,101,1,10,10,4,10,108,0,8,10,4,10,1001,8,0,88,1006,0,2,1006,0,62,2,8,2,10,3,8,1002,8,-1,10,101,1,10,10,4,10,1008,8,1,10,4,10,102,1,8,121,1006,0,91,1006,0,22,1006,0,23,1006,0,1,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,1,10,4,10,101,0,8,155,1006,0,97,1,1004,2,10,2,1003,6,10,3,8,1002,8,-1,10,101,1,10,10,4,10,108,0,8,10,4,10,1002,8,1,187,1,104,15,10,2,107,9,10,1006,0,37,1006,0,39,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,0,8,10,4,10,102,1,8,223,2,2,17,10,1,1102,5,10,3,8,1002,8,-1,10,101,1,10,10,4,10,108,0,8,10,4,10,1001,8,0,253,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,1,10,4,10,1002,8,1,276,1006,0,84,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,0,10,4,10,1001,8,0,301,2,1009,9,10,1006,0,10,2,102,15,10,101,1,9,9,1007,9,997,10,1005,10,15,99,109,654,104,0,104,1,21102,1,936995738516,1,21101,0,349,0,1105,1,453,21102,1,825595015976,1,21102,1,360,0,1105,1,453,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,21102,46375541763,1,1,21101,0,407,0,1105,1,453,21102,1,179339005019,1,21101,0,418,0,1106,0,453,3,10,104,0,104,0,3,10,104,0,104,0,21102,825012036372,1,1,21102,441,1,0,1105,1,453,21101,988648461076,0,1,21101,452,0,0,1105,1,453,99,109,2,22102,1,-1,1,21102,40,1,2,21102,484,1,3,21101,0,474,0,1106,0,517,109,-2,2105,1,0,0,1,0,0,1,109,2,3,10,204,-1,1001,479,480,495,4,0,1001,479,1,479,108,4,479,10,1006,10,511,1102,1,0,479,109,-2,2105,1,0,0,109,4,2102,1,-1,516,1207,-3,0,10,1006,10,534,21101,0,0,-3,21202,-3,1,1,22101,0,-2,2,21102,1,1,3,21102,553,1,0,1106,0,558,109,-4,2106,0,0,109,5,1207,-3,1,10,1006,10,581,2207,-4,-2,10,1006,10,581,22102,1,-4,-4,1105,1,649,21202,-4,1,1,21201,-3,-1,2,21202,-2,2,3,21101,0,600,0,1105,1,558,21201,1,0,-4,21101,0,1,-1,2207,-4,-2,10,1006,10,619,21101,0,0,-1,22202,-2,-1,-2,2107,0,-3,10,1006,10,641,22102,1,-1,1,21102,1,641,0,106,0,516,21202,-2,-1,-2,22201,-4,-2,-4,109,-5,2105,1,0 diff --git a/src/image.rs b/src/image.rs index 7d0d6f3..3783aa8 100644 --- a/src/image.rs +++ b/src/image.rs @@ -1,7 +1,7 @@ use bytecount::count; -const WHITE: char = ' '; -const BLACK: char = '\u{2588}'; +pub const WHITE: char = ' '; +pub const BLACK: char = '\u{2588}'; #[derive(Debug)] pub enum ImageParseError { diff --git a/src/machine.rs b/src/machine.rs index 0c728dd..402c0c9 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -17,7 +17,7 @@ const ADJUST_BASE: i64 = 9; const HALT: i64 = 99; #[derive(Debug,PartialEq)] -enum Mode { +pub enum Mode { Position, Immediate, Relative, diff --git a/src/main.rs b/src/main.rs index c062248..7b00b41 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ mod fuel; mod image; mod machine; mod orbits; +mod robot; mod wiremap; use crate::args::Command; diff --git a/src/robot.rs b/src/robot.rs new file mode 100644 index 0000000..8ea4edc --- /dev/null +++ b/src/robot.rs @@ -0,0 +1,152 @@ +use crate::endchannel::{Sender, Receiver, channel}; +use crate::machine::Computer; +use image::{ImageBuffer, Rgb}; +use std::thread; + +struct HullGrid { + data: ImageBuffer, Vec>, + robot_x: u32, + robot_y: u32, + robot_dir: Direction, + sender: Sender, + receiver: Receiver, +} + +impl HullGrid { + fn new(width: u32, height: u32, computer_path: &str) -> HullGrid { + let mut init_computer = Computer::load(computer_path, 0); + let ( mysend, mut corecv) = channel(); + let (mut cosend, myrecv) = channel(); + + assert!(width & 1 == 1); + assert!(height & 1 == 1); + thread::spawn(move || init_computer.run(&mut corecv, &mut cosend)); + HullGrid { + data: ImageBuffer::new(width, height), + robot_x: width / 2, + robot_y: height / 2, + robot_dir: Direction::Up, + sender: mysend, + receiver: myrecv, + } + } + + fn is_white(&self) -> bool { + let cur = self.data.get_pixel(self.robot_x, self.robot_y); + cur == &Rgb([0xff,0xff,0xff]) + } + + fn set_black(&mut self) { + self.data.put_pixel(self.robot_x, self.robot_y, Rgb([0x00,0x00,0x00])); + } + + fn set_white(&mut self) { + self.data.put_pixel(self.robot_x, self.robot_y, Rgb([0xff,0xff,0xff])); + } + + fn step(&mut self) { + match self.robot_dir { + Direction::Up => self.robot_y -= 1, + Direction::Down => self.robot_y += 1, + Direction::Right => self.robot_x += 1, + Direction::Left => self.robot_x -= 1, + } + } + + fn paint_next(&mut self) -> bool { + self.sender.send_ignore_error(if self.is_white() { 1 } else { 0 }); + match self.receiver.recv() { + None => + false, + Some(new_color) => { + let rotation = self.receiver.recv().expect("Didn't get rotation back"); + if new_color == 0 { self.set_black() } else { self.set_white() } + self.robot_dir = if rotation == 0 { + self.robot_dir.rotate_right() + } else { + self.robot_dir.rotate_left() + }; + self.step(); + true + } + } + } + + fn paint_hull(&mut self) -> usize { + let mut points = vec![]; + + while self.paint_next() { + let cur = (self.robot_x, self.robot_y); + if !points.contains(&cur) { + points.push(cur); + } + } + + points.len() + } + + fn render(&self, file: &str) { + self.data.save(file); + } +} + +#[derive(Debug,PartialEq)] +enum Direction { + Up, + Down, + Left, + Right, +} + +impl Direction { + fn rotate_right(&self) -> Direction { + match self { + Direction::Up => Direction::Right, + Direction::Right => Direction::Down, + Direction::Down => Direction::Left, + Direction::Left => Direction::Up, + } + } + + fn rotate_left(&self) -> Direction { + match self { + Direction::Up => Direction::Left, + + Direction::Right => Direction::Up, + Direction::Down => Direction::Right, + Direction::Left => Direction::Down, + } + } +} + +#[test] +fn rotations_work() { + assert_eq!(Direction::Up, Direction::Up.rotate_right().rotate_left()); + assert_eq!(Direction::Up, Direction::Up.rotate_left().rotate_right()); + assert_eq!(Direction::Right, Direction::Right.rotate_right().rotate_left()); + assert_eq!(Direction::Right, Direction::Right.rotate_left().rotate_right()); + assert_eq!(Direction::Down, Direction::Down.rotate_right().rotate_left()); + assert_eq!(Direction::Down, Direction::Down.rotate_left().rotate_right()); + assert_eq!(Direction::Left, Direction::Left.rotate_right().rotate_left()); + assert_eq!(Direction::Left, Direction::Left.rotate_left().rotate_right()); + /* */ + assert_eq!(Direction::Left, Direction::Left.rotate_right().rotate_right().rotate_right().rotate_right()); + assert_eq!(Direction::Right, Direction::Right.rotate_right().rotate_right().rotate_right().rotate_right()); + assert_eq!(Direction::Down, Direction::Down.rotate_right().rotate_right().rotate_right().rotate_right()); + assert_eq!(Direction::Up, Direction::Up.rotate_right().rotate_right().rotate_right().rotate_right()); + /* */ + assert_eq!(Direction::Left, Direction::Left.rotate_left().rotate_left().rotate_left().rotate_left()); + assert_eq!(Direction::Right, Direction::Right.rotate_left().rotate_left().rotate_left().rotate_left()); + assert_eq!(Direction::Down, Direction::Down.rotate_left().rotate_left().rotate_left().rotate_left()); + assert_eq!(Direction::Up, Direction::Up.rotate_left().rotate_left().rotate_left().rotate_left()); +} + +#[test] +fn day11() { + let mut day1a = HullGrid::new(1001, 1001, "inputs/day11"); + assert_eq!(2373, day1a.paint_hull()); + let mut day1b = HullGrid::new(1001, 1001, "inputs/day11"); + day1b.set_white(); + assert_eq!(249, day1b.paint_hull()); + day1b.render("day1.png"); +} \ No newline at end of file