This commit is contained in:
2019-12-18 21:57:48 -08:00
parent 726052cc6a
commit 0840e8e642
6 changed files with 158 additions and 3 deletions

View File

@@ -9,3 +9,4 @@ edition = "2018"
[dependencies] [dependencies]
bytecount = "^0.6.0" bytecount = "^0.6.0"
clap = "^2.33.0" clap = "^2.33.0"
image = "^0.22.0"

1
inputs/day11 Normal file
View File

@@ -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

View File

@@ -1,7 +1,7 @@
use bytecount::count; use bytecount::count;
const WHITE: char = ' '; pub const WHITE: char = ' ';
const BLACK: char = '\u{2588}'; pub const BLACK: char = '\u{2588}';
#[derive(Debug)] #[derive(Debug)]
pub enum ImageParseError { pub enum ImageParseError {

View File

@@ -17,7 +17,7 @@ const ADJUST_BASE: i64 = 9;
const HALT: i64 = 99; const HALT: i64 = 99;
#[derive(Debug,PartialEq)] #[derive(Debug,PartialEq)]
enum Mode { pub enum Mode {
Position, Position,
Immediate, Immediate,
Relative, Relative,

View File

@@ -4,6 +4,7 @@ mod fuel;
mod image; mod image;
mod machine; mod machine;
mod orbits; mod orbits;
mod robot;
mod wiremap; mod wiremap;
use crate::args::Command; use crate::args::Command;

152
src/robot.rs Normal file
View File

@@ -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<Rgb<u8>, Vec<u8>>,
robot_x: u32,
robot_y: u32,
robot_dir: Direction,
sender: Sender<i64>,
receiver: Receiver<i64>,
}
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");
}