Completed day 7 part 2
so behind! :o
This commit is contained in:
parent
74d77382dd
commit
7beabbf7c9
1
day7/input/test4.txt
Normal file
1
day7/input/test4.txt
Normal file
@ -0,0 +1 @@
|
||||
3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5
|
1
day7/input/test5.txt
Normal file
1
day7/input/test5.txt
Normal file
@ -0,0 +1 @@
|
||||
3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10
|
@ -12,7 +12,9 @@ type Result<T> = result::Result<T, Box<dyn Error>>;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Intcode {
|
||||
integers: Vec<i32>,
|
||||
pub integers: Vec<i32>,
|
||||
pub pointer: usize,
|
||||
pub halted: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@ -105,16 +107,23 @@ impl FromStr for Intcode {
|
||||
fn from_str(s: &str) -> Result<Intcode> {
|
||||
let intcode_string = s.trim().to_string();
|
||||
|
||||
Ok(Intcode {
|
||||
integers: intcode_string
|
||||
Ok(Intcode::new(
|
||||
intcode_string
|
||||
.split(',')
|
||||
.map(|code| code.parse().unwrap())
|
||||
.collect(),
|
||||
})
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl Intcode {
|
||||
fn new(integers: Vec<i32>) -> Intcode {
|
||||
Intcode {
|
||||
integers,
|
||||
pointer: 0,
|
||||
halted: false,
|
||||
}
|
||||
}
|
||||
fn load_parameters(&self, pointer: usize, instruction: &Instruction) -> Vec<i32> {
|
||||
(0..instruction.opcode.parameter_count() as usize)
|
||||
.map(|parameter_index| {
|
||||
@ -134,13 +143,12 @@ impl Intcode {
|
||||
}
|
||||
|
||||
pub fn execute(&mut self, inputs: &[i32]) -> Result<Vec<i32>> {
|
||||
let mut pointer = 0;
|
||||
let mut input_index = 0;
|
||||
let mut output = vec![];
|
||||
|
||||
loop {
|
||||
let instruction = Instruction::try_from(self.integers[pointer])?;
|
||||
let parameters = self.load_parameters(pointer, &instruction);
|
||||
let instruction = Instruction::try_from(self.integers[self.pointer])?;
|
||||
let parameters = self.load_parameters(self.pointer, &instruction);
|
||||
let mut jump_pointer: Option<usize> = None;
|
||||
|
||||
match instruction.opcode {
|
||||
@ -151,6 +159,9 @@ impl Intcode {
|
||||
self.integers[parameters[2] as usize] = parameters[0] * parameters[1];
|
||||
}
|
||||
Opcode::Input => {
|
||||
if input_index >= inputs.len() {
|
||||
break; // pause execution to wait for more input
|
||||
}
|
||||
self.integers[parameters[0] as usize] = inputs[input_index];
|
||||
input_index += 1;
|
||||
}
|
||||
@ -182,13 +193,14 @@ impl Intcode {
|
||||
}
|
||||
}
|
||||
Opcode::Halt => {
|
||||
self.halted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
match jump_pointer {
|
||||
Some(jump_pointer) => pointer = jump_pointer,
|
||||
None => pointer += 1 + instruction.opcode.parameter_count() as usize,
|
||||
Some(jump_pointer) => self.pointer = jump_pointer,
|
||||
None => self.pointer += 1 + instruction.opcode.parameter_count() as usize,
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,9 +226,7 @@ mod tests {
|
||||
fn reads_intcode() {
|
||||
assert_eq!(
|
||||
read_intcode(TEST_INPUT).unwrap(),
|
||||
Intcode {
|
||||
integers: vec![3, 15, 3, 16, 1002, 16, 10, 16, 1, 16, 15, 15, 4, 15, 99, 0, 0]
|
||||
},
|
||||
Intcode::new(vec![3, 15, 3, 16, 1002, 16, 10, 16, 1, 16, 15, 15, 4, 15, 99, 0, 0]),
|
||||
);
|
||||
}
|
||||
|
||||
@ -249,33 +259,23 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn executes_intcodes() {
|
||||
let mut intcode = Intcode {
|
||||
integers: vec![1, 0, 0, 0, 99],
|
||||
};
|
||||
let mut intcode = Intcode::new(vec![1, 0, 0, 0, 99]);
|
||||
intcode.execute(&[0]).unwrap();
|
||||
assert_eq!(intcode.integers, vec![2, 0, 0, 0, 99]);
|
||||
|
||||
let mut intcode = Intcode {
|
||||
integers: vec![2, 3, 0, 3, 99],
|
||||
};
|
||||
let mut intcode = Intcode::new(vec![2, 3, 0, 3, 99]);
|
||||
intcode.execute(&[0]).unwrap();
|
||||
assert_eq!(intcode.integers, vec![2, 3, 0, 6, 99]);
|
||||
|
||||
let mut intcode = Intcode {
|
||||
integers: vec![2, 4, 4, 5, 99, 0],
|
||||
};
|
||||
let mut intcode = Intcode::new(vec![2, 4, 4, 5, 99, 0]);
|
||||
intcode.execute(&[0]).unwrap();
|
||||
assert_eq!(intcode.integers, vec![2, 4, 4, 5, 99, 9801]);
|
||||
|
||||
let mut intcode = Intcode {
|
||||
integers: vec![1, 1, 1, 4, 99, 5, 6, 0, 99],
|
||||
};
|
||||
let mut intcode = Intcode::new(vec![1, 1, 1, 4, 99, 5, 6, 0, 99]);
|
||||
intcode.execute(&[0]).unwrap();
|
||||
assert_eq!(intcode.integers, vec![30, 1, 1, 4, 2, 5, 6, 0, 99]);
|
||||
|
||||
let mut intcode = Intcode {
|
||||
integers: vec![1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50],
|
||||
};
|
||||
let mut intcode = Intcode::new(vec![1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50]);
|
||||
intcode.execute(&[0]).unwrap();
|
||||
assert_eq!(
|
||||
intcode.integers,
|
||||
@ -285,55 +285,41 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn less_and_equal_outputs() {
|
||||
let intcode = Intcode {
|
||||
integers: vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8],
|
||||
};
|
||||
let intcode = Intcode::new(vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8]);
|
||||
assert_eq!(intcode.clone().execute(&[8]).unwrap(), vec![1]);
|
||||
assert_eq!(intcode.clone().execute(&[0]).unwrap(), vec![0]);
|
||||
|
||||
let intcode = Intcode {
|
||||
integers: vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8],
|
||||
};
|
||||
let intcode = Intcode::new(vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8]);
|
||||
assert_eq!(intcode.clone().execute(&[0]).unwrap(), vec![1]);
|
||||
assert_eq!(intcode.clone().execute(&[9]).unwrap(), vec![0]);
|
||||
|
||||
let intcode = Intcode {
|
||||
integers: vec![3, 3, 1108, -1, 8, 3, 4, 3, 99],
|
||||
};
|
||||
let intcode = Intcode::new(vec![3, 3, 1108, -1, 8, 3, 4, 3, 99]);
|
||||
assert_eq!(intcode.clone().execute(&[8]).unwrap(), vec![1]);
|
||||
assert_eq!(intcode.clone().execute(&[0]).unwrap(), vec![0]);
|
||||
|
||||
let intcode = Intcode {
|
||||
integers: vec![3, 3, 1107, -1, 8, 3, 4, 3, 99],
|
||||
};
|
||||
let intcode = Intcode::new(vec![3, 3, 1107, -1, 8, 3, 4, 3, 99]);
|
||||
assert_eq!(intcode.clone().execute(&[0]).unwrap(), vec![1]);
|
||||
assert_eq!(intcode.clone().execute(&[9]).unwrap(), vec![0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn jump_outputs() {
|
||||
let intcode = Intcode {
|
||||
integers: vec![3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9],
|
||||
};
|
||||
let intcode = Intcode::new(vec![3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9]);
|
||||
assert_eq!(intcode.clone().execute(&[0]).unwrap(), vec![0]);
|
||||
assert_eq!(intcode.clone().execute(&[1]).unwrap(), vec![1]);
|
||||
|
||||
let intcode = Intcode {
|
||||
integers: vec![3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1],
|
||||
};
|
||||
let intcode = Intcode::new(vec![3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1]);
|
||||
assert_eq!(intcode.clone().execute(&[0]).unwrap(), vec![0]);
|
||||
assert_eq!(intcode.clone().execute(&[1]).unwrap(), vec![1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn larger_part2_intcode() {
|
||||
let intcode = Intcode {
|
||||
integers: vec![
|
||||
let intcode = Intcode::new(vec![
|
||||
3, 21, 1008, 21, 8, 20, 1005, 20, 22, 107, 8, 21, 20, 1006, 20, 31, 1106, 0, 36,
|
||||
98, 0, 0, 1002, 21, 125, 20, 4, 20, 1105, 1, 46, 104, 999, 1105, 1, 46, 1101, 1000,
|
||||
1, 20, 4, 20, 1105, 1, 46, 98, 99,
|
||||
],
|
||||
};
|
||||
]);
|
||||
assert_eq!(intcode.clone().execute(&[0]).unwrap(), vec![999]);
|
||||
assert_eq!(intcode.clone().execute(&[8]).unwrap(), vec![1000]);
|
||||
assert_eq!(intcode.clone().execute(&[9]).unwrap(), vec![1001]);
|
||||
@ -341,11 +327,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn multiple_input_intcode() {
|
||||
let intcode = Intcode {
|
||||
integers: vec![
|
||||
let intcode = Intcode::new(vec![
|
||||
3, 15, 3, 16, 1002, 16, 10, 16, 1, 16, 15, 15, 4, 15, 99, 0, 0,
|
||||
],
|
||||
};
|
||||
]);
|
||||
assert_eq!(intcode.clone().execute(&[1, 1]).unwrap(), vec![11]);
|
||||
}
|
||||
}
|
||||
|
@ -14,69 +14,84 @@ type Result<T> = result::Result<T, Box<dyn Error>>;
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
struct Amplifier {
|
||||
intcode: Intcode,
|
||||
phase_setting: i32,
|
||||
}
|
||||
|
||||
impl Amplifier {
|
||||
fn new(intcode: Intcode, phase_setting: i32) -> Amplifier {
|
||||
fn new(intcode: Intcode) -> Amplifier {
|
||||
Amplifier {
|
||||
intcode: intcode,
|
||||
phase_setting: phase_setting,
|
||||
}
|
||||
}
|
||||
|
||||
fn execute(&self, input: i32) -> Result<i32> {
|
||||
let mut intcode = self.intcode.clone();
|
||||
let output = intcode.execute(&[self.phase_setting, input])?;
|
||||
dbg!(&output);
|
||||
Ok(output[0])
|
||||
fn reset_intcode(&mut self, intcode: Intcode) {
|
||||
self.intcode = intcode;
|
||||
}
|
||||
|
||||
fn execute(&mut self, input: i32) -> Result<Vec<i32>> {
|
||||
let output = self.intcode.execute(&[input])?;
|
||||
Ok(output)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
struct AmplificationCircuit {
|
||||
amplifiers: Vec<Amplifier>,
|
||||
intcode: Intcode,
|
||||
}
|
||||
|
||||
impl AmplificationCircuit {
|
||||
fn new(
|
||||
intcode: Intcode,
|
||||
amplifier_count: usize,
|
||||
initial_phase_settings: &[i32],
|
||||
) -> AmplificationCircuit {
|
||||
AmplificationCircuit {
|
||||
amplifiers: (0..amplifier_count)
|
||||
.map(|index| Amplifier::new(intcode.clone(), initial_phase_settings[index]))
|
||||
.map(|_| Amplifier::new(intcode.clone()))
|
||||
.collect(),
|
||||
intcode,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_phase_settings(&mut self, phase_settings: &[i32; 5]) {
|
||||
fn set_phase_settings(&mut self, phase_settings: &[i32; 5]) -> Result<()> {
|
||||
for (index, phase_setting) in phase_settings.iter().enumerate() {
|
||||
self.amplifiers[index].phase_setting = *phase_setting;
|
||||
self.amplifiers[index].execute(*phase_setting)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn reset_circuit(&mut self) {
|
||||
for amplifier in self.amplifiers.iter_mut() {
|
||||
amplifier.reset_intcode(self.intcode.clone());
|
||||
}
|
||||
}
|
||||
|
||||
fn execute_circuit(&self, input_signal: i32) -> Result<i32> {
|
||||
fn execute_circuit(&mut self, input_signal: i32) -> Result<i32> {
|
||||
let mut input = input_signal;
|
||||
for amplifier in self.amplifiers.iter() {
|
||||
input = amplifier.execute(input)?;
|
||||
while !self.amplifiers[4].intcode.halted {
|
||||
for amplifier in self.amplifiers.iter_mut() {
|
||||
input = amplifier.execute(input)?[0];
|
||||
}
|
||||
}
|
||||
Ok(input)
|
||||
}
|
||||
|
||||
fn find_max_output(&mut self, input_signal: i32) -> Result<i32> {
|
||||
let mut phase_setting: [i32; 5] = [0, 1, 2, 3, 4];
|
||||
fn find_max_output(
|
||||
&mut self,
|
||||
input_signal: i32,
|
||||
phase_setting_options: [i32; 5],
|
||||
) -> Result<i32> {
|
||||
let mut phase_setting: [i32; 5] = phase_setting_options;
|
||||
let mut max_output = 0;
|
||||
let heap = Heap::new(&mut phase_setting);
|
||||
|
||||
for permutation in heap {
|
||||
self.set_phase_settings(&permutation);
|
||||
self.set_phase_settings(&permutation)?;
|
||||
|
||||
let output = self.execute_circuit(input_signal)?;
|
||||
if output > max_output {
|
||||
max_output = output;
|
||||
}
|
||||
self.reset_circuit();
|
||||
}
|
||||
|
||||
Ok(max_output)
|
||||
@ -85,12 +100,14 @@ impl AmplificationCircuit {
|
||||
|
||||
fn solve_part1() -> Result<i32> {
|
||||
let intcode = read_intcode(INPUT)?;
|
||||
let mut circuit = AmplificationCircuit::new(intcode, 5, &[0, 0, 0, 0, 0]);
|
||||
Ok(circuit.find_max_output(0)?)
|
||||
let mut circuit = AmplificationCircuit::new(intcode, 5);
|
||||
Ok(circuit.find_max_output(0, [0, 1, 2, 3, 4])?)
|
||||
}
|
||||
|
||||
fn solve_part2() -> Result<i32> {
|
||||
Ok(0)
|
||||
let intcode = read_intcode(INPUT)?;
|
||||
let mut circuit = AmplificationCircuit::new(intcode, 5);
|
||||
Ok(circuit.find_max_output(0, [5, 6, 7, 8, 9])?)
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
@ -107,19 +124,24 @@ mod tests {
|
||||
const TEST_INPUT1: &str = "input/test1.txt";
|
||||
const TEST_INPUT2: &str = "input/test2.txt";
|
||||
const TEST_INPUT3: &str = "input/test3.txt";
|
||||
const TEST_INPUT4: &str = "input/test4.txt";
|
||||
const TEST_INPUT5: &str = "input/test5.txt";
|
||||
|
||||
#[test]
|
||||
fn executes_amplifier_circuits() {
|
||||
let intcode = read_intcode(TEST_INPUT1).unwrap();
|
||||
let circuit = AmplificationCircuit::new(intcode, 5, &[4, 3, 2, 1, 0]);
|
||||
let mut circuit = AmplificationCircuit::new(intcode, 5);
|
||||
circuit.set_phase_settings(&[4, 3, 2, 1, 0]).unwrap();
|
||||
assert_eq!(circuit.execute_circuit(0).unwrap(), 43210);
|
||||
|
||||
let intcode = read_intcode(TEST_INPUT2).unwrap();
|
||||
let circuit = AmplificationCircuit::new(intcode, 5, &[0, 1, 2, 3, 4]);
|
||||
let mut circuit = AmplificationCircuit::new(intcode, 5);
|
||||
circuit.set_phase_settings(&[0, 1, 2, 3, 4]).unwrap();
|
||||
assert_eq!(circuit.execute_circuit(0).unwrap(), 54321);
|
||||
|
||||
let intcode = read_intcode(TEST_INPUT3).unwrap();
|
||||
let circuit = AmplificationCircuit::new(intcode, 5, &[1, 0, 4, 3, 2]);
|
||||
let mut circuit = AmplificationCircuit::new(intcode, 5);
|
||||
circuit.set_phase_settings(&[1, 0, 4, 3, 2]).unwrap();
|
||||
assert_eq!(circuit.execute_circuit(0).unwrap(), 65210);
|
||||
}
|
||||
|
||||
@ -129,8 +151,32 @@ mod tests {
|
||||
let outputs = [43210, 54321, 65210];
|
||||
for (input, output) in inputs.iter().zip(outputs.iter()) {
|
||||
let intcode = read_intcode(input).unwrap();
|
||||
let mut circuit = AmplificationCircuit::new(intcode, 5, &[0, 0, 0, 0, 0]);
|
||||
assert_eq!(circuit.find_max_output(0).unwrap(), *output);
|
||||
let mut circuit = AmplificationCircuit::new(intcode, 5);
|
||||
assert_eq!(circuit.find_max_output(0, [0, 1, 2, 3, 4]).unwrap(), *output);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn executes_feedback_loop_amplifier_circuits() {
|
||||
let intcode = read_intcode(TEST_INPUT4).unwrap();
|
||||
let mut circuit = AmplificationCircuit::new(intcode, 5);
|
||||
circuit.set_phase_settings(&[9, 8, 7, 6, 5]).unwrap();
|
||||
assert_eq!(circuit.execute_circuit(0).unwrap(), 139629729);
|
||||
|
||||
let intcode = read_intcode(TEST_INPUT5).unwrap();
|
||||
let mut circuit = AmplificationCircuit::new(intcode, 5);
|
||||
circuit.set_phase_settings(&[9, 7, 8, 5, 6]).unwrap();
|
||||
assert_eq!(circuit.execute_circuit(0).unwrap(), 18216);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finds_max_outputs_of_feedback_loop_circuits() {
|
||||
let inputs = [TEST_INPUT4, TEST_INPUT5];
|
||||
let outputs = [139629729, 18216];
|
||||
for (input, output) in inputs.iter().zip(outputs.iter()) {
|
||||
let intcode = read_intcode(input).unwrap();
|
||||
let mut circuit = AmplificationCircuit::new(intcode, 5);
|
||||
assert_eq!(circuit.find_max_output(0, [5, 6, 7, 8, 9]).unwrap(), *output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user