Day 11!
This commit is contained in:
@@ -9,3 +9,4 @@ edition = "2018"
|
||||
[dependencies]
|
||||
bytecount = "^0.6.0"
|
||||
clap = "^2.33.0"
|
||||
image = "^0.22.0"
|
||||
1
inputs/day11
Normal file
1
inputs/day11
Normal 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
|
||||
@@ -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 {
|
||||
|
||||
@@ -17,7 +17,7 @@ const ADJUST_BASE: i64 = 9;
|
||||
const HALT: i64 = 99;
|
||||
|
||||
#[derive(Debug,PartialEq)]
|
||||
enum Mode {
|
||||
pub enum Mode {
|
||||
Position,
|
||||
Immediate,
|
||||
Relative,
|
||||
|
||||
@@ -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
152
src/robot.rs
Normal 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");
|
||||
}
|
||||
Reference in New Issue
Block a user