A not totally terrible day 19 solution.
This commit is contained in:
@@ -10,6 +10,7 @@ mod repair;
|
||||
mod robot;
|
||||
#[cfg(test)]
|
||||
mod scaffold;
|
||||
mod tractor;
|
||||
mod wiremap;
|
||||
|
||||
use crate::args::Command;
|
||||
|
||||
134
src/tractor.rs
Normal file
134
src/tractor.rs
Normal file
@@ -0,0 +1,134 @@
|
||||
use crate::endchannel::channel;
|
||||
use crate::machine::Computer;
|
||||
use std::thread;
|
||||
|
||||
struct TractorMap {
|
||||
base_computer: Computer,
|
||||
data: Vec<bool>,
|
||||
width: usize,
|
||||
affected_size: usize,
|
||||
}
|
||||
|
||||
impl TractorMap {
|
||||
fn new(file: &str, side_size: usize) -> TractorMap {
|
||||
let base_computer = Computer::load(file, 0);
|
||||
let mut result = Vec::with_capacity(side_size * side_size);
|
||||
let mut affected = 0;
|
||||
|
||||
result.resize(side_size * side_size, false);
|
||||
for x in 0..side_size {
|
||||
for y in 0..side_size {
|
||||
let mut computer = base_computer.clone();
|
||||
let ( mysend, mut corecv) = channel();
|
||||
let (mut cosend, mut myrecv) = channel();
|
||||
|
||||
mysend.send(x as i64);
|
||||
mysend.send(y as i64);
|
||||
computer.run(&mut corecv, &mut cosend);
|
||||
match myrecv.recv() {
|
||||
None => panic!("Uh-oh, computer broken!"),
|
||||
Some(0) => {}
|
||||
Some(1) => {
|
||||
affected += 1;
|
||||
let idx = (y * side_size) + x;
|
||||
result[idx] = true;
|
||||
}
|
||||
Some(x) => panic!("Weird value {}", x),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TractorMap {
|
||||
base_computer,
|
||||
data: result,
|
||||
width: side_size,
|
||||
affected_size: affected,
|
||||
}
|
||||
}
|
||||
|
||||
fn ask(&self, x: usize, y: usize) -> bool {
|
||||
let mut computer = self.base_computer.clone();
|
||||
let ( mysend, mut corecv) = channel();
|
||||
let (mut cosend, mut myrecv) = channel();
|
||||
|
||||
mysend.send(x as i64);
|
||||
mysend.send(y as i64);
|
||||
computer.run(&mut corecv, &mut cosend);
|
||||
match myrecv.recv() {
|
||||
None => panic!("Uh-oh, computer broken!"),
|
||||
Some(0) => false,
|
||||
Some(1) => true,
|
||||
Some(x) => panic!("Weird value {}", x),
|
||||
}
|
||||
}
|
||||
|
||||
fn find_block(&self, start: (usize, usize), side_size: usize) -> Option<(usize, usize)> {
|
||||
let mut xl = start.0;
|
||||
let mut yl = start.1;
|
||||
|
||||
loop {
|
||||
let mut reset_x = 0;
|
||||
|
||||
loop {
|
||||
if self.ask(xl, yl) {
|
||||
if reset_x == 0 {
|
||||
reset_x = xl;
|
||||
}
|
||||
|
||||
let xr = xl + side_size - 1;
|
||||
let yr = yl + side_size - 1;
|
||||
|
||||
if self.ask(xl, yr) && self.ask(xr, yl) && self.ask(xr, yr) {
|
||||
return Some((xl, yl));
|
||||
}
|
||||
|
||||
xl += 1;
|
||||
} else {
|
||||
if reset_x != 0 {
|
||||
break;
|
||||
} else {
|
||||
xl += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xl = reset_x;
|
||||
yl += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn print(&self) {
|
||||
for y in 0..self.width {
|
||||
for x in 0..self.width {
|
||||
// if ((x >= 20) && (x <= 22)) && ((y >= 16) && (y <= 18)) {
|
||||
// assert!(self.data[ (y * self.width) + x ]);
|
||||
// print!("X");
|
||||
// continue;
|
||||
// }
|
||||
if self.data[ (y * self.width) + x ] {
|
||||
print!("#");
|
||||
} else {
|
||||
print!(".");
|
||||
}
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn day19a() {
|
||||
let tmap = TractorMap::new("inputs/day19", 50);
|
||||
assert_eq!(223, tmap.affected_size);
|
||||
tmap.print();
|
||||
assert_eq!(Some((20, 16)), tmap.find_block((0, 6), 3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn day19b() {
|
||||
let tmap = TractorMap::new("inputs/day19", 50);
|
||||
let (x, y) = tmap.find_block((10, 16), 100).expect("a solution");
|
||||
assert_eq!(948, x);
|
||||
assert_eq!(761, y);
|
||||
assert_eq!(9480761, (x * 10000) + y);
|
||||
}
|
||||
Reference in New Issue
Block a user