day07 task 2

This commit is contained in:
Johannes
2019-12-08 20:50:46 +01:00
parent 0db2018217
commit da5cf69b1b
2 changed files with 116 additions and 0 deletions

View File

@@ -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] { pub fn get_output(&self) -> &[i32] {
self.output_storage.as_slice() self.output_storage.as_slice()
} }

View File

@@ -9,6 +9,7 @@ pub fn run() {
.map(|s| s.parse::<i32>().unwrap()) .map(|s| s.parse::<i32>().unwrap())
.collect(); .collect();
task1(prog_code.clone()); task1(prog_code.clone());
task2(prog_code.clone());
} }
fn task1(input: Vec<i32>) { fn task1(input: Vec<i32>) {
@@ -26,3 +27,37 @@ fn task1(input: Vec<i32>) {
.max(); .max();
println!("Task 1: best signal is {}", result.unwrap()); println!("Task 1: best signal is {}", result.unwrap());
} }
fn task2(input: Vec<i32>) {
let phases = vec![5, 6, 7, 8, 9];
let result = phases
.iter()
.permutations(phases.len())
.map(|perm| {
let mut machines: Vec<IntCodeComputer> = 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());
}