From da5cf69b1b97ec2991cfe6fbbb995d79498c6d3c Mon Sep 17 00:00:00 2001 From: Johannes Date: Sun, 8 Dec 2019 20:50:46 +0100 Subject: [PATCH] day07 task 2 --- src/tasks/day05.rs | 81 ++++++++++++++++++++++++++++++++++++++++++++++ src/tasks/day07.rs | 35 ++++++++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/src/tasks/day05.rs b/src/tasks/day05.rs index e468327..7d1b543 100644 --- a/src/tasks/day05.rs +++ b/src/tasks/day05.rs @@ -212,6 +212,87 @@ impl IntCodeComputer { } } + /** + * True means the program terminated, false means it is just waiting for more input + */ + pub fn run_until_input_empty(&mut self) -> bool { + let mut op = Op::from(self.pc, &self.ram); + let mut inputs = self.input_storage.iter(); + while op.opcode != OpCode::Terminate { + match op.opcode { + OpCode::Add => { + let r = op.params[0].retrieve(&self.ram) + op.params[1].retrieve(&self.ram); + op.params[2].store(&mut self.ram, r); + self.pc += 4; + } + OpCode::Multiply => { + let r = op.params[0].retrieve(&self.ram) * op.params[1].retrieve(&self.ram); + op.params[2].store(&mut self.ram, r); + self.pc += 4; + } + OpCode::Input => { + if let Some(v) = inputs.next() { + op.params[0].store(&mut self.ram, *v); + self.pc += 2; + } else { + return false; + } + } + OpCode::Output => { + self.output_storage.push(op.params[0].retrieve(&self.ram)); + self.pc += 2; + } + OpCode::JumpIfTrue => { + if op.params[0].retrieve(&self.ram) > 0 { + self.pc = op.params[1].retrieve(&self.ram) as usize; + } else { + self.pc += 3; + } + } + OpCode::JumpIfFalse => { + if op.params[0].retrieve(&self.ram) == 0 { + self.pc = op.params[1].retrieve(&self.ram) as usize; + } else { + self.pc += 3; + } + } + OpCode::LessThan => { + let r = if op.params[0].retrieve(&self.ram) < op.params[1].retrieve(&self.ram) { + 1 + } else { + 0 + }; + op.params[2].store(&mut self.ram, r); + self.pc += 4; + } + OpCode::Equals => { + let r = if op.params[0].retrieve(&self.ram) == op.params[1].retrieve(&self.ram) + { + 1 + } else { + 0 + }; + op.params[2].store(&mut self.ram, r); + self.pc += 4; + } + OpCode::Terminate => {} + } + op = Op::from(self.pc, &self.ram); + } + return true; + } + + pub fn set_input(&mut self, input: &[i32]) { + self.input_storage.clear(); + for x in input { + self.input_storage.push(*x); + } + } + + pub fn clear_output(&mut self) { + self.output_storage.clear(); + } + pub fn get_output(&self) -> &[i32] { self.output_storage.as_slice() } diff --git a/src/tasks/day07.rs b/src/tasks/day07.rs index 9898deb..4a31e32 100644 --- a/src/tasks/day07.rs +++ b/src/tasks/day07.rs @@ -9,6 +9,7 @@ pub fn run() { .map(|s| s.parse::().unwrap()) .collect(); task1(prog_code.clone()); + task2(prog_code.clone()); } fn task1(input: Vec) { @@ -26,3 +27,37 @@ fn task1(input: Vec) { .max(); println!("Task 1: best signal is {}", result.unwrap()); } + +fn task2(input: Vec) { + let phases = vec![5, 6, 7, 8, 9]; + let result = phases + .iter() + .permutations(phases.len()) + .map(|perm| { + let mut machines: Vec = perm + .iter() + .map(|phase| { + let mut comp = IntCodeComputer::new(vec![**phase], input.clone()); + comp.run_until_input_empty(); + comp + }) + .collect(); + let mut m = 0; + let mut signal = 0; + let mut done = false; + while !done { + let mach = &mut machines[m]; + mach.set_input(&vec![signal]); + let machine_done = mach.run_until_input_empty(); + signal = *mach.get_output().last().unwrap(); + mach.clear_output(); + if machine_done && m == 4 { + done = true; + } + m = (m + 1) % machines.len(); + } + signal + }) + .max(); + println!("Task 2: best signal with looping is {}", result.unwrap()); +}