day07 task 2
This commit is contained in:
@@ -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()
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ pub fn run() {
|
||||
.map(|s| s.parse::<i32>().unwrap())
|
||||
.collect();
|
||||
task1(prog_code.clone());
|
||||
task2(prog_code.clone());
|
||||
}
|
||||
|
||||
fn task1(input: Vec<i32>) {
|
||||
@@ -26,3 +27,37 @@ fn task1(input: Vec<i32>) {
|
||||
.max();
|
||||
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());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user