Browse Source

Completed day 7 part 2

so behind! :o
Tyler Hallada 4 years ago
parent
commit
7beabbf7c9
4 changed files with 111 additions and 79 deletions
  1. 1 0
      day7/input/test4.txt
  2. 1 0
      day7/input/test5.txt
  3. 37 53
      day7/src/intcode.rs
  4. 72 26
      day7/src/main.rs

+ 1 - 0
day7/input/test4.txt

@@ -0,0 +1 @@
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 - 0
day7/input/test5.txt

@@ -0,0 +1 @@
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

+ 37 - 53
day7/src/intcode.rs

@@ -12,7 +12,9 @@ type Result<T> = result::Result<T, Box<dyn Error>>;
12 12
 
13 13
 #[derive(Debug, Clone, PartialEq)]
14 14
 pub struct Intcode {
15
-    integers: Vec<i32>,
15
+    pub integers: Vec<i32>,
16
+    pub pointer: usize,
17
+    pub halted: bool,
16 18
 }
17 19
 
18 20
 #[derive(Debug, PartialEq)]
@@ -105,16 +107,23 @@ impl FromStr for Intcode {
105 107
     fn from_str(s: &str) -> Result<Intcode> {
106 108
         let intcode_string = s.trim().to_string();
107 109
 
108
-        Ok(Intcode {
109
-            integers: intcode_string
110
+        Ok(Intcode::new(
111
+            intcode_string
110 112
                 .split(',')
111 113
                 .map(|code| code.parse().unwrap())
112 114
                 .collect(),
113
-        })
115
+        ))
114 116
     }
115 117
 }
116 118
 
117 119
 impl Intcode {
120
+    fn new(integers: Vec<i32>) -> Intcode {
121
+        Intcode {
122
+            integers,
123
+            pointer: 0,
124
+            halted: false,
125
+        }
126
+    }
118 127
     fn load_parameters(&self, pointer: usize, instruction: &Instruction) -> Vec<i32> {
119 128
         (0..instruction.opcode.parameter_count() as usize)
120 129
             .map(|parameter_index| {
@@ -134,13 +143,12 @@ impl Intcode {
134 143
     }
135 144
 
136 145
     pub fn execute(&mut self, inputs: &[i32]) -> Result<Vec<i32>> {
137
-        let mut pointer = 0;
138 146
         let mut input_index = 0;
139 147
         let mut output = vec![];
140 148
 
141 149
         loop {
142
-            let instruction = Instruction::try_from(self.integers[pointer])?;
143
-            let parameters = self.load_parameters(pointer, &instruction);
150
+            let instruction = Instruction::try_from(self.integers[self.pointer])?;
151
+            let parameters = self.load_parameters(self.pointer, &instruction);
144 152
             let mut jump_pointer: Option<usize> = None;
145 153
 
146 154
             match instruction.opcode {
@@ -151,6 +159,9 @@ impl Intcode {
151 159
                     self.integers[parameters[2] as usize] = parameters[0] * parameters[1];
152 160
                 }
153 161
                 Opcode::Input => {
162
+                    if input_index >= inputs.len() {
163
+                        break; // pause execution to wait for more input
164
+                    }
154 165
                     self.integers[parameters[0] as usize] = inputs[input_index];
155 166
                     input_index += 1;
156 167
                 }
@@ -182,13 +193,14 @@ impl Intcode {
182 193
                     }
183 194
                 }
184 195
                 Opcode::Halt => {
196
+                    self.halted = true;
185 197
                     break;
186 198
                 }
187 199
             }
188 200
 
189 201
             match jump_pointer {
190
-                Some(jump_pointer) => pointer = jump_pointer,
191
-                None => pointer += 1 + instruction.opcode.parameter_count() as usize,
202
+                Some(jump_pointer) => self.pointer = jump_pointer,
203
+                None => self.pointer += 1 + instruction.opcode.parameter_count() as usize,
192 204
             }
193 205
         }
194 206
 
@@ -214,9 +226,7 @@ mod tests {
214 226
     fn reads_intcode() {
215 227
         assert_eq!(
216 228
             read_intcode(TEST_INPUT).unwrap(),
217
-            Intcode {
218
-                integers: vec![3, 15, 3, 16, 1002, 16, 10, 16, 1, 16, 15, 15, 4, 15, 99, 0, 0]
219
-            },
229
+            Intcode::new(vec![3, 15, 3, 16, 1002, 16, 10, 16, 1, 16, 15, 15, 4, 15, 99, 0, 0]),
220 230
         );
221 231
     }
222 232
 
@@ -249,33 +259,23 @@ mod tests {
249 259
 
250 260
     #[test]
251 261
     fn executes_intcodes() {
252
-        let mut intcode = Intcode {
253
-            integers: vec![1, 0, 0, 0, 99],
254
-        };
262
+        let mut intcode = Intcode::new(vec![1, 0, 0, 0, 99]);
255 263
         intcode.execute(&[0]).unwrap();
256 264
         assert_eq!(intcode.integers, vec![2, 0, 0, 0, 99]);
257 265
 
258
-        let mut intcode = Intcode {
259
-            integers: vec![2, 3, 0, 3, 99],
260
-        };
266
+        let mut intcode = Intcode::new(vec![2, 3, 0, 3, 99]);
261 267
         intcode.execute(&[0]).unwrap();
262 268
         assert_eq!(intcode.integers, vec![2, 3, 0, 6, 99]);
263 269
 
264
-        let mut intcode = Intcode {
265
-            integers: vec![2, 4, 4, 5, 99, 0],
266
-        };
270
+        let mut intcode = Intcode::new(vec![2, 4, 4, 5, 99, 0]);
267 271
         intcode.execute(&[0]).unwrap();
268 272
         assert_eq!(intcode.integers, vec![2, 4, 4, 5, 99, 9801]);
269 273
 
270
-        let mut intcode = Intcode {
271
-            integers: vec![1, 1, 1, 4, 99, 5, 6, 0, 99],
272
-        };
274
+        let mut intcode = Intcode::new(vec![1, 1, 1, 4, 99, 5, 6, 0, 99]);
273 275
         intcode.execute(&[0]).unwrap();
274 276
         assert_eq!(intcode.integers, vec![30, 1, 1, 4, 2, 5, 6, 0, 99]);
275 277
 
276
-        let mut intcode = Intcode {
277
-            integers: vec![1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50],
278
-        };
278
+        let mut intcode = Intcode::new(vec![1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50]);
279 279
         intcode.execute(&[0]).unwrap();
280 280
         assert_eq!(
281 281
             intcode.integers,
@@ -285,55 +285,41 @@ mod tests {
285 285
 
286 286
     #[test]
287 287
     fn less_and_equal_outputs() {
288
-        let intcode = Intcode {
289
-            integers: vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8],
290
-        };
288
+        let intcode = Intcode::new(vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8]);
291 289
         assert_eq!(intcode.clone().execute(&[8]).unwrap(), vec![1]);
292 290
         assert_eq!(intcode.clone().execute(&[0]).unwrap(), vec![0]);
293 291
 
294
-        let intcode = Intcode {
295
-            integers: vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8],
296
-        };
292
+        let intcode = Intcode::new(vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8]);
297 293
         assert_eq!(intcode.clone().execute(&[0]).unwrap(), vec![1]);
298 294
         assert_eq!(intcode.clone().execute(&[9]).unwrap(), vec![0]);
299 295
 
300
-        let intcode = Intcode {
301
-            integers: vec![3, 3, 1108, -1, 8, 3, 4, 3, 99],
302
-        };
296
+        let intcode = Intcode::new(vec![3, 3, 1108, -1, 8, 3, 4, 3, 99]);
303 297
         assert_eq!(intcode.clone().execute(&[8]).unwrap(), vec![1]);
304 298
         assert_eq!(intcode.clone().execute(&[0]).unwrap(), vec![0]);
305 299
 
306
-        let intcode = Intcode {
307
-            integers: vec![3, 3, 1107, -1, 8, 3, 4, 3, 99],
308
-        };
300
+        let intcode = Intcode::new(vec![3, 3, 1107, -1, 8, 3, 4, 3, 99]);
309 301
         assert_eq!(intcode.clone().execute(&[0]).unwrap(), vec![1]);
310 302
         assert_eq!(intcode.clone().execute(&[9]).unwrap(), vec![0]);
311 303
     }
312 304
 
313 305
     #[test]
314 306
     fn jump_outputs() {
315
-        let intcode = Intcode {
316
-            integers: vec![3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9],
317
-        };
307
+        let intcode = Intcode::new(vec![3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9]);
318 308
         assert_eq!(intcode.clone().execute(&[0]).unwrap(), vec![0]);
319 309
         assert_eq!(intcode.clone().execute(&[1]).unwrap(), vec![1]);
320 310
 
321
-        let intcode = Intcode {
322
-            integers: vec![3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1],
323
-        };
311
+        let intcode = Intcode::new(vec![3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1]);
324 312
         assert_eq!(intcode.clone().execute(&[0]).unwrap(), vec![0]);
325 313
         assert_eq!(intcode.clone().execute(&[1]).unwrap(), vec![1]);
326 314
     }
327 315
 
328 316
     #[test]
329 317
     fn larger_part2_intcode() {
330
-        let intcode = Intcode {
331
-            integers: vec![
318
+        let intcode = Intcode::new(vec![
332 319
                 3, 21, 1008, 21, 8, 20, 1005, 20, 22, 107, 8, 21, 20, 1006, 20, 31, 1106, 0, 36,
333 320
                 98, 0, 0, 1002, 21, 125, 20, 4, 20, 1105, 1, 46, 104, 999, 1105, 1, 46, 1101, 1000,
334 321
                 1, 20, 4, 20, 1105, 1, 46, 98, 99,
335
-            ],
336
-        };
322
+            ]);
337 323
         assert_eq!(intcode.clone().execute(&[0]).unwrap(), vec![999]);
338 324
         assert_eq!(intcode.clone().execute(&[8]).unwrap(), vec![1000]);
339 325
         assert_eq!(intcode.clone().execute(&[9]).unwrap(), vec![1001]);
@@ -341,11 +327,9 @@ mod tests {
341 327
 
342 328
     #[test]
343 329
     fn multiple_input_intcode() {
344
-        let intcode = Intcode {
345
-            integers: vec![
330
+        let intcode = Intcode::new(vec![
346 331
                 3, 15, 3, 16, 1002, 16, 10, 16, 1, 16, 15, 15, 4, 15, 99, 0, 0,
347
-            ],
348
-        };
332
+            ]);
349 333
         assert_eq!(intcode.clone().execute(&[1, 1]).unwrap(), vec![11]);
350 334
     }
351 335
 }

+ 72 - 26
day7/src/main.rs

@@ -14,69 +14,84 @@ type Result<T> = result::Result<T, Box<dyn Error>>;
14 14
 #[derive(Debug, Clone, PartialEq)]
15 15
 struct Amplifier {
16 16
     intcode: Intcode,
17
-    phase_setting: i32,
18 17
 }
19 18
 
20 19
 impl Amplifier {
21
-    fn new(intcode: Intcode, phase_setting: i32) -> Amplifier {
20
+    fn new(intcode: Intcode) -> Amplifier {
22 21
         Amplifier {
23 22
             intcode: intcode,
24
-            phase_setting: phase_setting,
25 23
         }
26 24
     }
27 25
 
28
-    fn execute(&self, input: i32) -> Result<i32> {
29
-        let mut intcode = self.intcode.clone();
30
-        let output = intcode.execute(&[self.phase_setting, input])?;
31
-        dbg!(&output);
32
-        Ok(output[0])
26
+    fn reset_intcode(&mut self, intcode: Intcode) {
27
+        self.intcode = intcode;
28
+    }
29
+
30
+    fn execute(&mut self, input: i32) -> Result<Vec<i32>> {
31
+        let output = self.intcode.execute(&[input])?;
32
+        Ok(output)
33 33
     }
34 34
 }
35 35
 
36 36
 #[derive(Debug, Clone, PartialEq)]
37 37
 struct AmplificationCircuit {
38 38
     amplifiers: Vec<Amplifier>,
39
+    intcode: Intcode,
39 40
 }
40 41
 
41 42
 impl AmplificationCircuit {
42 43
     fn new(
43 44
         intcode: Intcode,
44 45
         amplifier_count: usize,
45
-        initial_phase_settings: &[i32],
46 46
     ) -> AmplificationCircuit {
47 47
         AmplificationCircuit {
48 48
             amplifiers: (0..amplifier_count)
49
-                .map(|index| Amplifier::new(intcode.clone(), initial_phase_settings[index]))
49
+                .map(|_| Amplifier::new(intcode.clone()))
50 50
                 .collect(),
51
+            intcode,
51 52
         }
52 53
     }
53 54
 
54
-    fn set_phase_settings(&mut self, phase_settings: &[i32; 5]) {
55
+    fn set_phase_settings(&mut self, phase_settings: &[i32; 5]) -> Result<()> {
55 56
         for (index, phase_setting) in phase_settings.iter().enumerate() {
56
-            self.amplifiers[index].phase_setting = *phase_setting;
57
+            self.amplifiers[index].execute(*phase_setting)?;
57 58
         }
59
+        Ok(())
58 60
     }
59 61
 
60
-    fn execute_circuit(&self, input_signal: i32) -> Result<i32> {
62
+    fn reset_circuit(&mut self) {
63
+        for amplifier in self.amplifiers.iter_mut() {
64
+            amplifier.reset_intcode(self.intcode.clone());
65
+        }
66
+    }
67
+
68
+    fn execute_circuit(&mut self, input_signal: i32) -> Result<i32> {
61 69
         let mut input = input_signal;
62
-        for amplifier in self.amplifiers.iter() {
63
-            input = amplifier.execute(input)?;
70
+        while !self.amplifiers[4].intcode.halted {
71
+            for amplifier in self.amplifiers.iter_mut() {
72
+                input = amplifier.execute(input)?[0];
73
+            }
64 74
         }
65 75
         Ok(input)
66 76
     }
67 77
 
68
-    fn find_max_output(&mut self, input_signal: i32) -> Result<i32> {
69
-        let mut phase_setting: [i32; 5] = [0, 1, 2, 3, 4];
78
+    fn find_max_output(
79
+        &mut self,
80
+        input_signal: i32,
81
+        phase_setting_options: [i32; 5],
82
+    ) -> Result<i32> {
83
+        let mut phase_setting: [i32; 5] = phase_setting_options;
70 84
         let mut max_output = 0;
71 85
         let heap = Heap::new(&mut phase_setting);
72 86
 
73 87
         for permutation in heap {
74
-            self.set_phase_settings(&permutation);
88
+            self.set_phase_settings(&permutation)?;
75 89
 
76 90
             let output = self.execute_circuit(input_signal)?;
77 91
             if output > max_output {
78 92
                 max_output = output;
79 93
             }
94
+            self.reset_circuit();
80 95
         }
81 96
 
82 97
         Ok(max_output)
@@ -85,12 +100,14 @@ impl AmplificationCircuit {
85 100
 
86 101
 fn solve_part1() -> Result<i32> {
87 102
     let intcode = read_intcode(INPUT)?;
88
-    let mut circuit = AmplificationCircuit::new(intcode, 5, &[0, 0, 0, 0, 0]);
89
-    Ok(circuit.find_max_output(0)?)
103
+    let mut circuit = AmplificationCircuit::new(intcode, 5);
104
+    Ok(circuit.find_max_output(0, [0, 1, 2, 3, 4])?)
90 105
 }
91 106
 
92 107
 fn solve_part2() -> Result<i32> {
93
-    Ok(0)
108
+    let intcode = read_intcode(INPUT)?;
109
+    let mut circuit = AmplificationCircuit::new(intcode, 5);
110
+    Ok(circuit.find_max_output(0, [5, 6, 7, 8, 9])?)
94 111
 }
95 112
 
96 113
 fn main() -> Result<()> {
@@ -107,19 +124,24 @@ mod tests {
107 124
     const TEST_INPUT1: &str = "input/test1.txt";
108 125
     const TEST_INPUT2: &str = "input/test2.txt";
109 126
     const TEST_INPUT3: &str = "input/test3.txt";
127
+    const TEST_INPUT4: &str = "input/test4.txt";
128
+    const TEST_INPUT5: &str = "input/test5.txt";
110 129
 
111 130
     #[test]
112 131
     fn executes_amplifier_circuits() {
113 132
         let intcode = read_intcode(TEST_INPUT1).unwrap();
114
-        let circuit = AmplificationCircuit::new(intcode, 5, &[4, 3, 2, 1, 0]);
133
+        let mut circuit = AmplificationCircuit::new(intcode, 5);
134
+        circuit.set_phase_settings(&[4, 3, 2, 1, 0]).unwrap();
115 135
         assert_eq!(circuit.execute_circuit(0).unwrap(), 43210);
116 136
 
117 137
         let intcode = read_intcode(TEST_INPUT2).unwrap();
118
-        let circuit = AmplificationCircuit::new(intcode, 5, &[0, 1, 2, 3, 4]);
138
+        let mut circuit = AmplificationCircuit::new(intcode, 5);
139
+        circuit.set_phase_settings(&[0, 1, 2, 3, 4]).unwrap();
119 140
         assert_eq!(circuit.execute_circuit(0).unwrap(), 54321);
120 141
 
121 142
         let intcode = read_intcode(TEST_INPUT3).unwrap();
122
-        let circuit = AmplificationCircuit::new(intcode, 5, &[1, 0, 4, 3, 2]);
143
+        let mut circuit = AmplificationCircuit::new(intcode, 5);
144
+        circuit.set_phase_settings(&[1, 0, 4, 3, 2]).unwrap();
123 145
         assert_eq!(circuit.execute_circuit(0).unwrap(), 65210);
124 146
     }
125 147
 
@@ -129,8 +151,32 @@ mod tests {
129 151
         let outputs = [43210, 54321, 65210];
130 152
         for (input, output) in inputs.iter().zip(outputs.iter()) {
131 153
             let intcode = read_intcode(input).unwrap();
132
-            let mut circuit = AmplificationCircuit::new(intcode, 5, &[0, 0, 0, 0, 0]);
133
-            assert_eq!(circuit.find_max_output(0).unwrap(), *output);
154
+            let mut circuit = AmplificationCircuit::new(intcode, 5);
155
+            assert_eq!(circuit.find_max_output(0, [0, 1, 2, 3, 4]).unwrap(), *output);
156
+        }
157
+    }
158
+
159
+    #[test]
160
+    fn executes_feedback_loop_amplifier_circuits() {
161
+        let intcode = read_intcode(TEST_INPUT4).unwrap();
162
+        let mut circuit = AmplificationCircuit::new(intcode, 5);
163
+        circuit.set_phase_settings(&[9, 8, 7, 6, 5]).unwrap();
164
+        assert_eq!(circuit.execute_circuit(0).unwrap(), 139629729);
165
+
166
+        let intcode = read_intcode(TEST_INPUT5).unwrap();
167
+        let mut circuit = AmplificationCircuit::new(intcode, 5);
168
+        circuit.set_phase_settings(&[9, 7, 8, 5, 6]).unwrap();
169
+        assert_eq!(circuit.execute_circuit(0).unwrap(), 18216);
170
+    }
171
+
172
+    #[test]
173
+    fn finds_max_outputs_of_feedback_loop_circuits() {
174
+        let inputs = [TEST_INPUT4, TEST_INPUT5];
175
+        let outputs = [139629729, 18216];
176
+        for (input, output) in inputs.iter().zip(outputs.iter()) {
177
+            let intcode = read_intcode(input).unwrap();
178
+            let mut circuit = AmplificationCircuit::new(intcode, 5);
179
+            assert_eq!(circuit.find_max_output(0, [5, 6, 7, 8, 9]).unwrap(), *output);
134 180
         }
135 181
     }
136 182
 }