diff --git a/inputs/day19 b/inputs/day19 new file mode 100644 index 0000000..5db3a24 --- /dev/null +++ b/inputs/day19 @@ -0,0 +1 @@ +109,424,203,1,21101,0,11,0,1105,1,282,21101,18,0,0,1105,1,259,1202,1,1,221,203,1,21102,1,31,0,1106,0,282,21102,38,1,0,1106,0,259,21002,23,1,2,22102,1,1,3,21102,1,1,1,21102,1,57,0,1105,1,303,2102,1,1,222,20101,0,221,3,21001,221,0,2,21102,259,1,1,21102,1,80,0,1106,0,225,21102,62,1,2,21101,91,0,0,1105,1,303,2101,0,1,223,21001,222,0,4,21101,0,259,3,21101,0,225,2,21101,0,225,1,21101,0,118,0,1105,1,225,20102,1,222,3,21101,94,0,2,21102,133,1,0,1105,1,303,21202,1,-1,1,22001,223,1,1,21101,0,148,0,1105,1,259,1202,1,1,223,20101,0,221,4,21001,222,0,3,21102,17,1,2,1001,132,-2,224,1002,224,2,224,1001,224,3,224,1002,132,-1,132,1,224,132,224,21001,224,1,1,21101,195,0,0,105,1,109,20207,1,223,2,20101,0,23,1,21102,-1,1,3,21101,214,0,0,1106,0,303,22101,1,1,1,204,1,99,0,0,0,0,109,5,2101,0,-4,249,22102,1,-3,1,22101,0,-2,2,21201,-1,0,3,21102,1,250,0,1106,0,225,22101,0,1,-4,109,-5,2105,1,0,109,3,22107,0,-2,-1,21202,-1,2,-1,21201,-1,-1,-1,22202,-1,-2,-2,109,-3,2106,0,0,109,3,21207,-2,0,-1,1206,-1,294,104,0,99,22101,0,-2,-2,109,-3,2106,0,0,109,5,22207,-3,-4,-1,1206,-1,346,22201,-4,-3,-4,21202,-3,-1,-1,22201,-4,-1,2,21202,2,-1,-1,22201,-4,-1,1,21201,-2,0,3,21101,343,0,0,1106,0,303,1105,1,415,22207,-2,-3,-1,1206,-1,387,22201,-3,-2,-3,21202,-2,-1,-1,22201,-3,-1,3,21202,3,-1,-1,22201,-3,-1,2,22102,1,-4,1,21102,384,1,0,1105,1,303,1105,1,415,21202,-4,-1,-4,22201,-4,-3,-4,22202,-3,-2,-2,22202,-2,-4,-4,22202,-3,-2,-3,21202,-4,-1,-2,22201,-3,-2,1,21201,1,0,-4,109,-5,2105,1,0 diff --git a/src/main.rs b/src/main.rs index e5187a7..decda5d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,7 @@ mod repair; mod robot; #[cfg(test)] mod scaffold; +mod tractor; mod wiremap; use crate::args::Command; diff --git a/src/tractor.rs b/src/tractor.rs new file mode 100644 index 0000000..a18146b --- /dev/null +++ b/src/tractor.rs @@ -0,0 +1,134 @@ +use crate::endchannel::channel; +use crate::machine::Computer; +use std::thread; + +struct TractorMap { + base_computer: Computer, + data: Vec, + 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); +} \ No newline at end of file