mirror of
https://github.com/wezm/advent-of-code.git
synced 2024-12-18 10:19:55 +00:00
Day 11
This commit is contained in:
parent
2f53e2ac8b
commit
672b0964a1
5 changed files with 202 additions and 9 deletions
151
2019/src/bin/day11.rs
Normal file
151
2019/src/bin/day11.rs
Normal file
|
@ -0,0 +1,151 @@
|
|||
use std::{fs, io};
|
||||
|
||||
use advent_of_code::computer::{ComputeResult, Computer};
|
||||
use advent_of_code::input;
|
||||
use advent_of_code::point::Point;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Rotate {
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
||||
enum Direction {
|
||||
North,
|
||||
South,
|
||||
East,
|
||||
West,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Robot {
|
||||
heading: Direction,
|
||||
position: Point,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
||||
enum Colour {
|
||||
Black,
|
||||
White,
|
||||
}
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let input = fs::read_to_string("input/day11.txt")?;
|
||||
let program = input::read_separated_line(',', &input)?;
|
||||
|
||||
let painted = run_robot(Colour::Black, program.clone());
|
||||
println!("Part 1: {}", painted.len());
|
||||
|
||||
let painted = run_robot(Colour::White, program.clone());
|
||||
// Determine dimensions of image
|
||||
let minx = painted.iter().map(|(point, _)| point.0).min().unwrap();
|
||||
let maxx = painted.iter().map(|(point, _)| point.0).max().unwrap();
|
||||
let miny = painted.iter().map(|(point, _)| point.1).min().unwrap();
|
||||
let maxy = painted.iter().map(|(point, _)| point.1).max().unwrap();
|
||||
|
||||
println!();
|
||||
for y in (miny..=maxy).rev() {
|
||||
for x in minx..=maxx {
|
||||
match painted.get(&Point(x, y)) {
|
||||
Some(Colour::White) => print!("█"),
|
||||
Some(Colour::Black) | None => print!(" "),
|
||||
}
|
||||
}
|
||||
println!();
|
||||
}
|
||||
println!();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_robot(initial_colour: Colour, program: Vec<i64>) -> HashMap<Point, Colour> {
|
||||
let mut robot = Robot::new();
|
||||
let mut painted = HashMap::new();
|
||||
let initial_input = match initial_colour {
|
||||
Colour::Black => 0,
|
||||
Colour::White => 1,
|
||||
};
|
||||
let mut computer = Computer::new('1', program, vec![initial_input], vec![]);
|
||||
|
||||
loop {
|
||||
match computer.run(None, None) {
|
||||
ComputeResult::Halted => break,
|
||||
ComputeResult::NeedsInput => {
|
||||
let output = computer.output().to_vec();
|
||||
painted.insert(robot.position, Colour::from(output[0]));
|
||||
let rotation = Rotate::from(output[1]);
|
||||
robot.rotate(rotation);
|
||||
robot.go_forward();
|
||||
computer.clear_output();
|
||||
|
||||
let tile_colour = painted
|
||||
.get(&robot.position)
|
||||
.map(|colour| match colour {
|
||||
Colour::Black => 0,
|
||||
Colour::White => 1,
|
||||
})
|
||||
.unwrap_or(0);
|
||||
computer.input(tile_colour);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
painted
|
||||
}
|
||||
|
||||
impl Robot {
|
||||
fn new() -> Self {
|
||||
Robot {
|
||||
heading: Direction::North,
|
||||
position: Point(0, 0),
|
||||
}
|
||||
}
|
||||
|
||||
fn rotate(&mut self, rotate: Rotate) {
|
||||
self.heading = match rotate {
|
||||
Rotate::Left => match self.heading {
|
||||
Direction::North => Direction::West,
|
||||
Direction::South => Direction::East,
|
||||
Direction::East => Direction::North,
|
||||
Direction::West => Direction::South,
|
||||
},
|
||||
Rotate::Right => match self.heading {
|
||||
Direction::North => Direction::East,
|
||||
Direction::South => Direction::West,
|
||||
Direction::East => Direction::South,
|
||||
Direction::West => Direction::North,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn go_forward(&mut self) {
|
||||
match self.heading {
|
||||
Direction::North => self.position.1 += 1,
|
||||
Direction::South => self.position.1 -= 1,
|
||||
Direction::East => self.position.0 += 1,
|
||||
Direction::West => self.position.0 -= 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i64> for Rotate {
|
||||
fn from(n: i64) -> Self {
|
||||
match n {
|
||||
0 => Rotate::Left,
|
||||
1 => Rotate::Right,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i64> for Colour {
|
||||
fn from(n: i64) -> Self {
|
||||
match n {
|
||||
0 => Colour::Black,
|
||||
1 => Colour::White,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,11 +7,11 @@ fn main() -> io::Result<()> {
|
|||
|
||||
let mut computer = computer::Computer::new('1', data.clone(), vec![1], vec![]);
|
||||
computer.run(None, None);
|
||||
println!("Part 1: {}", computer.output());
|
||||
println!("Part 1: {}", computer.last_output());
|
||||
|
||||
let mut computer = computer::Computer::new('2', data.clone(), vec![5], vec![]);
|
||||
computer.run(None, None);
|
||||
println!("Part 2: {}", computer.output());
|
||||
println!("Part 2: {}", computer.last_output());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ fn part1(data: Vec<i64>) {
|
|||
let mut computer = Computer::new(name, data.clone(), input, vec![]);
|
||||
name = char::try_from(name as u32 + 1).unwrap();
|
||||
computer.run(None, None);
|
||||
output = computer.output();
|
||||
output = computer.last_output();
|
||||
}
|
||||
output
|
||||
})
|
||||
|
|
|
@ -9,11 +9,11 @@ fn main() -> io::Result<()> {
|
|||
|
||||
let mut computer = Computer::new('1', program.clone(), vec![1], vec![]);
|
||||
computer.run(None, None);
|
||||
println!("Part 1: {}", computer.output());
|
||||
println!("Part 1: {}", computer.last_output());
|
||||
|
||||
let mut computer = Computer::new('2', program.clone(), vec![2], vec![]);
|
||||
computer.run(None, None);
|
||||
println!("Part 2: {}", computer.output());
|
||||
println!("Part 2: {}", computer.last_output());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ mod tests {
|
|||
let mut computer = Computer::new('T', program, vec![], vec![]);
|
||||
computer.run(None, None);
|
||||
|
||||
assert_eq!(computer.output(), 1219070632396864);
|
||||
assert_eq!(computer.last_output(), 1219070632396864);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -39,7 +39,7 @@ mod tests {
|
|||
let mut computer = Computer::new('T', program, vec![], vec![]);
|
||||
computer.run(None, None);
|
||||
|
||||
assert_eq!(computer.output(), 99);
|
||||
assert_eq!(computer.last_output(), 99);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -48,6 +48,6 @@ mod tests {
|
|||
let mut computer = Computer::new('T', program, vec![], vec![]);
|
||||
computer.run(None, None);
|
||||
|
||||
assert_eq!(computer.output(), 1125899906842624);
|
||||
assert_eq!(computer.last_output(), 1125899906842624);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,18 +51,28 @@ pub struct Computer<I: Input, O: Output> {
|
|||
|
||||
pub trait Input {
|
||||
fn read(&mut self) -> Option<i64>;
|
||||
|
||||
fn push(&mut self, val: i64);
|
||||
}
|
||||
|
||||
pub trait Output {
|
||||
fn write(&mut self, value: i64);
|
||||
|
||||
fn last_value(&self) -> i64;
|
||||
|
||||
fn get(&self) -> &[i64];
|
||||
|
||||
fn clear(&mut self);
|
||||
}
|
||||
|
||||
impl Input for Vec<i64> {
|
||||
fn read(&mut self) -> Option<i64> {
|
||||
self.pop()
|
||||
}
|
||||
|
||||
fn push(&mut self, val: i64) {
|
||||
self.insert(0, val)
|
||||
}
|
||||
}
|
||||
|
||||
impl Output for Vec<i64> {
|
||||
|
@ -73,12 +83,24 @@ impl Output for Vec<i64> {
|
|||
fn last_value(&self) -> i64 {
|
||||
*self.last().unwrap()
|
||||
}
|
||||
|
||||
fn get(&self) -> &[i64] {
|
||||
self
|
||||
}
|
||||
|
||||
fn clear(&mut self) {
|
||||
self.clear()
|
||||
}
|
||||
}
|
||||
|
||||
impl Input for Rc<RefCell<Pipe>> {
|
||||
fn read(&mut self) -> Option<i64> {
|
||||
dbg!(self.borrow_mut().queue.pop_front())
|
||||
}
|
||||
|
||||
fn push(&mut self, val: i64) {
|
||||
self.borrow_mut().queue.push_back(val)
|
||||
}
|
||||
}
|
||||
|
||||
impl Output for Rc<RefCell<Pipe>> {
|
||||
|
@ -91,6 +113,14 @@ impl Output for Rc<RefCell<Pipe>> {
|
|||
fn last_value(&self) -> i64 {
|
||||
self.borrow().last.unwrap()
|
||||
}
|
||||
|
||||
fn get(&self) -> &[i64] {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn clear(&mut self) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
fn decode(mut instruction: i64) -> Instruction {
|
||||
|
@ -253,9 +283,21 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub fn output(&self) -> i64 {
|
||||
pub fn last_output(&self) -> i64 {
|
||||
self.output.last_value()
|
||||
}
|
||||
|
||||
pub fn input(&mut self, val: i64) {
|
||||
self.input.push(val)
|
||||
}
|
||||
|
||||
pub fn output(&self) -> &[i64] {
|
||||
self.output.get()
|
||||
}
|
||||
|
||||
pub fn clear_output(&mut self) {
|
||||
self.output.clear()
|
||||
}
|
||||
}
|
||||
|
||||
impl Pipe {
|
||||
|
|
Loading…
Reference in a new issue