Day 23, part 1.

This commit is contained in:
2019-12-23 17:24:06 -08:00
parent 06e9229370
commit 22be48c596
4 changed files with 125 additions and 0 deletions

View File

@@ -10,5 +10,6 @@ edition = "2018"
bytecount = "^0.6.0"
clap = "^2.33.0"
image = "^0.22.0"
itertools = "^0.8.0"
rand = "^0.7"
terminal_graphics = "^0.1.5"

1
inputs/day23 Normal file

File diff suppressed because one or more lines are too long

View File

@@ -9,6 +9,8 @@ mod repair;
#[cfg(test)]
mod robot;
#[cfg(test)]
mod router;
#[cfg(test)]
mod scaffold;
#[cfg(test)]
mod tractor;

121
src/router.rs Normal file
View File

@@ -0,0 +1,121 @@
use crate::machine::{Computer, RunResult};
use itertools::Itertools;
use std::collections::{HashMap, VecDeque};
use std::ops::Range;
struct ComputerState {
next: Box<dyn FnOnce(i64) -> Computer>,
input_queue: VecDeque<i64>,
}
impl ComputerState {
fn new(mut c: Computer, address: i64) -> ComputerState {
let mut sent_address = false;
loop {
match c.run() {
RunResult::Continue(next) =>
c = next,
RunResult::Halted(_) =>
panic!("Computer halted right away!"),
RunResult::Output(_, _) =>
panic!("Computer sent output right away!"),
RunResult::Input(f) if sent_address =>
return ComputerState {
next: f,
input_queue: VecDeque::new(),
},
RunResult::Input(f) => {
c = f(address);
sent_address = true;
}
}
}
}
fn run(mut self, output: &mut VecDeque<i64>) -> Option<Self> {
let mut c = match self.input_queue.pop_front() {
None => (self.next)(-1),
Some(x) => (self.next)(x),
};
loop {
match c.run() {
RunResult::Continue(next) =>
c = next,
RunResult::Halted(_) =>
return None,
RunResult::Output(o, next) => {
output.push_back(o);
c = next;
}
RunResult::Input(f) =>
match self.input_queue.pop_front() {
None => {
self.next = f;
return Some(self);
}
Some(x) =>
c = f(x),
}
}
}
}
}
struct Router {
map: HashMap<usize, ComputerState>
}
impl Router {
fn new(file: &str, nodes: Range<usize>) -> Router {
let mut map = HashMap::new();
let c = Computer::load(file);
for i in nodes {
map.insert(i, ComputerState::new(c.clone(), i as i64));
}
Router{ map }
}
fn step(mut self) -> Self {
let mut outputs = VecDeque::new();
let mut res = HashMap::new();
for (key, val) in self.map.drain() {
match val.run(&mut outputs) {
None => {},
Some(new_state) => {
let _ = res.insert(key, new_state);
}
}
}
for (dest, x, y) in outputs.drain(0..).tuples() {
match res.get_mut(&(dest as usize)) {
None =>
panic!("Unknown destination {} (x {}, y {})", dest, x, y),
Some(state) => {
state.input_queue.push_back(x);
state.input_queue.push_back(y);
}
}
}
Router{ map: res }
}
fn run(mut self) -> Self {
while self.map.len() > 0 {
self = self.step();
}
self
}
}
#[test]
fn day23a() {
let router = Router::new("inputs/day23", 0..50);
router.run();
}