add day7 part2

This commit is contained in:
Stefan Schwarz 2020-04-20 22:56:31 +02:00
parent 01e15eccec
commit 35a15fb23f

View file

@ -110,7 +110,6 @@ struct Computer {
outputs: VecDeque<i64>,
halted: bool,
paused: bool,
}
impl Clone for Computer {
@ -146,7 +145,6 @@ impl From<Vec<i64>> for Computer {
inputs: VecDeque::new(),
outputs: VecDeque::new(),
halted: false,
paused: false,
}
}
}
@ -172,15 +170,28 @@ impl Computer {
}
}
fn run_until_output(&mut self) -> i64 {
fn run_until_output(&mut self) -> Option<i64> {
loop {
self.step();
if self.outputs.len() > 0 {
return self.outputs.pop_front().unwrap();
return self.outputs.pop_front();
}
if self.halted {
return None;
}
}
}
fn run_must_output(&mut self) -> i64 {
self.run_until_output()
.expect("computer halted without output")
}
fn run_io(&mut self, input: Vec<i64>) -> Option<i64> {
input.iter().for_each(|i| self.inputs.push_back(*i));
self.run_until_output()
}
fn step(&mut self) {
let instruction = self.program[self.pos];
let instruction = ModedOpcode::from(instruction);
@ -317,17 +328,75 @@ fn main() -> io::Result<()> {
let filename = env::args().nth(1).expect("provide file as first param");
let computer = Computer::from(File::open(filename)?);
// part 1
let orders = build_args(vec![0, 1, 2, 3, 4], 5);
let results: (i64, String) = orders
.iter()
.map(|order| {
let mut amp_a = computer.clone_with_input(vec![order[0], 0]);
let mut amp_b = computer.clone_with_input(vec![order[1], amp_a.run_until_output()]);
let mut amp_c = computer.clone_with_input(vec![order[2], amp_b.run_until_output()]);
let mut amp_d = computer.clone_with_input(vec![order[3], amp_c.run_until_output()]);
let mut amp_e = computer.clone_with_input(vec![order[4], amp_d.run_until_output()]);
let mut amp_b = computer.clone_with_input(vec![order[1], amp_a.run_must_output()]);
let mut amp_c = computer.clone_with_input(vec![order[2], amp_b.run_must_output()]);
let mut amp_d = computer.clone_with_input(vec![order[3], amp_c.run_must_output()]);
let mut amp_e = computer.clone_with_input(vec![order[4], amp_d.run_must_output()]);
(
amp_e.run_until_output(),
amp_e.run_until_output().unwrap(),
order
.iter()
.map(|i| i.to_string())
.collect::<Vec<String>>()
.join(""),
)
})
.fold(None, |max, (output, order)| {
Some(match max {
None => (output, order),
Some((output_max, order_max)) => {
if output > output_max {
(output, order)
} else {
(output_max, order_max)
}
}
})
})
.unwrap();
println!("{:?}", results);
// part 2
let orders = build_args(vec![5, 6, 7, 8, 9], 5);
let results: (i64, String) = orders
.iter()
.map(|order| {
let mut amp_a = computer.clone_with_input(vec![order[0]]);
let mut amp_b = computer.clone_with_input(vec![order[1]]);
let mut amp_c = computer.clone_with_input(vec![order[2]]);
let mut amp_d = computer.clone_with_input(vec![order[3]]);
let mut amp_e = computer.clone_with_input(vec![order[4]]);
let mut to_a = 0;
loop {
let to_b = match amp_a.run_io(vec![to_a]) {
Some(v) => v,
None => break,
};
let to_c = match amp_b.run_io(vec![to_b]) {
Some(v) => v,
None => break,
};
let to_d = match amp_c.run_io(vec![to_c]) {
Some(v) => v,
None => break,
};
let to_e = match amp_d.run_io(vec![to_d]) {
Some(v) => v,
None => break,
};
to_a = match amp_e.run_io(vec![to_e]) {
Some(v) => v,
None => break,
};
}
(
to_a,
order
.iter()
.map(|i| i.to_string())