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

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

View File

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

View File

@@ -4,6 +4,7 @@ mod fuel;
mod image;
mod machine;
mod orbits;
mod robot;
mod wiremap;
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");
}