Browse Source

Completed day 5 part 2

Tyler Hallada 4 years ago
parent
commit
7799518c05
1 changed files with 104 additions and 6 deletions
  1. 104 6
      day5/src/main.rs

+ 104 - 6
day5/src/main.rs

@@ -11,7 +11,7 @@ const INPUT: &str = "input/input.txt";
11 11
 
12 12
 type Result<T> = result::Result<T, Box<dyn Error>>;
13 13
 
14
-#[derive(Debug, PartialEq)]
14
+#[derive(Debug, Clone, PartialEq)]
15 15
 struct Intcode {
16 16
     integers: Vec<i32>,
17 17
 }
@@ -56,6 +56,10 @@ enum Opcode {
56 56
     Mult = 2,
57 57
     Input = 3,
58 58
     Output = 4,
59
+    JumpIfTrue = 5,
60
+    JumpIfFalse = 6,
61
+    LessThan = 7,
62
+    Equals = 8,
59 63
     Halt = 99,
60 64
 }
61 65
 
@@ -66,6 +70,10 @@ impl Opcode {
66 70
             Opcode::Mult => 3,
67 71
             Opcode::Input => 1,
68 72
             Opcode::Output => 1,
73
+            Opcode::JumpIfTrue => 2,
74
+            Opcode::JumpIfFalse => 2,
75
+            Opcode::LessThan => 3,
76
+            Opcode::Equals => 3,
69 77
             Opcode::Halt => 0,
70 78
         }
71 79
     }
@@ -76,6 +84,10 @@ impl Opcode {
76 84
             Opcode::Mult => Some(2),
77 85
             Opcode::Input => Some(0),
78 86
             Opcode::Output => None,
87
+            Opcode::JumpIfTrue => None,
88
+            Opcode::JumpIfFalse => None,
89
+            Opcode::LessThan => Some(2),
90
+            Opcode::Equals => Some(2),
79 91
             Opcode::Halt => None,
80 92
         }
81 93
     }
@@ -129,6 +141,7 @@ impl Intcode {
129 141
         loop {
130 142
             let instruction = Instruction::try_from(self.integers[pointer])?;
131 143
             let parameters = self.load_parameters(pointer, &instruction);
144
+            let mut jump_pointer: Option<usize> = None;
132 145
 
133 146
             match instruction.opcode {
134 147
                 Opcode::Add => {
@@ -143,12 +156,39 @@ impl Intcode {
143 156
                 Opcode::Output => {
144 157
                     output.push(parameters[0]);
145 158
                 }
159
+                Opcode::JumpIfTrue => {
160
+                    if parameters[0] != 0 {
161
+                        jump_pointer = Some(parameters[1] as usize);
162
+                    }
163
+                }
164
+                Opcode::JumpIfFalse => {
165
+                    if parameters[0] == 0 {
166
+                        jump_pointer = Some(parameters[1] as usize);
167
+                    }
168
+                }
169
+                Opcode::LessThan => {
170
+                    if parameters[0] < parameters[1] {
171
+                        self.integers[parameters[2] as usize] = 1;
172
+                    } else {
173
+                        self.integers[parameters[2] as usize] = 0;
174
+                    }
175
+                }
176
+                Opcode::Equals => {
177
+                    if parameters[0] == parameters[1] {
178
+                        self.integers[parameters[2] as usize] = 1;
179
+                    } else {
180
+                        self.integers[parameters[2] as usize] = 0;
181
+                    }
182
+                }
146 183
                 Opcode::Halt => {
147 184
                     break;
148 185
                 }
149 186
             }
150 187
 
151
-            pointer += 1 + instruction.opcode.parameter_count() as usize;
188
+            match jump_pointer {
189
+                Some(jump_pointer) => pointer = jump_pointer,
190
+                None => pointer += 1 + instruction.opcode.parameter_count() as usize,
191
+            }
152 192
         }
153 193
 
154 194
         Ok(output)
@@ -168,12 +208,14 @@ fn solve_part1() -> Result<i32> {
168 208
     Ok(intcode.execute(1)?.into_iter().last().ok_or("No output")?)
169 209
 }
170 210
 
171
-// fn solve_part2() -> io::Result<i32> {
172
-// }
211
+fn solve_part2() -> Result<i32> {
212
+    let mut intcode = read_intcode(INPUT)?;
213
+    Ok(intcode.execute(5)?.into_iter().last().ok_or("No output")?)
214
+}
173 215
 
174 216
 fn main() -> Result<()> {
175
-    println!("Part 1: {:?}", solve_part1()?);
176
-    // println!("Part 2: {}", solve_part2()?);
217
+    println!("Part 1: {}", solve_part1()?);
218
+    println!("Part 2: {}", solve_part2()?);
177 219
 
178 220
     Ok(())
179 221
 }
@@ -256,4 +298,60 @@ mod tests {
256 298
             vec![3500, 9, 10, 70, 2, 3, 11, 0, 99, 30, 40, 50]
257 299
         );
258 300
     }
301
+
302
+    #[test]
303
+    fn less_and_equal_outputs() {
304
+        let intcode = Intcode {
305
+            integers: vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8],
306
+        };
307
+        assert_eq!(intcode.clone().execute(8).unwrap(), vec![1]);
308
+        assert_eq!(intcode.clone().execute(0).unwrap(), vec![0]);
309
+
310
+        let intcode = Intcode {
311
+            integers: vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8],
312
+        };
313
+        assert_eq!(intcode.clone().execute(0).unwrap(), vec![1]);
314
+        assert_eq!(intcode.clone().execute(9).unwrap(), vec![0]);
315
+
316
+        let intcode = Intcode {
317
+            integers: vec![3, 3, 1108, -1, 8, 3, 4, 3, 99],
318
+        };
319
+        assert_eq!(intcode.clone().execute(8).unwrap(), vec![1]);
320
+        assert_eq!(intcode.clone().execute(0).unwrap(), vec![0]);
321
+
322
+        let intcode = Intcode {
323
+            integers: vec![3, 3, 1107, -1, 8, 3, 4, 3, 99],
324
+        };
325
+        assert_eq!(intcode.clone().execute(0).unwrap(), vec![1]);
326
+        assert_eq!(intcode.clone().execute(9).unwrap(), vec![0]);
327
+    }
328
+
329
+    #[test]
330
+    fn jump_outputs() {
331
+        let intcode = Intcode {
332
+            integers: vec![3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9],
333
+        };
334
+        assert_eq!(intcode.clone().execute(0).unwrap(), vec![0]);
335
+        assert_eq!(intcode.clone().execute(1).unwrap(), vec![1]);
336
+
337
+        let intcode = Intcode {
338
+            integers: vec![3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1],
339
+        };
340
+        assert_eq!(intcode.clone().execute(0).unwrap(), vec![0]);
341
+        assert_eq!(intcode.clone().execute(1).unwrap(), vec![1]);
342
+    }
343
+
344
+    #[test]
345
+    fn larger_part2_intcode() {
346
+        let intcode = Intcode {
347
+            integers: vec![
348
+                3, 21, 1008, 21, 8, 20, 1005, 20, 22, 107, 8, 21, 20, 1006, 20, 31, 1106, 0, 36,
349
+                98, 0, 0, 1002, 21, 125, 20, 4, 20, 1105, 1, 46, 104, 999, 1105, 1, 46, 1101, 1000,
350
+                1, 20, 4, 20, 1105, 1, 46, 98, 99,
351
+            ],
352
+        };
353
+        assert_eq!(intcode.clone().execute(0).unwrap(), vec![999]);
354
+        assert_eq!(intcode.clone().execute(8).unwrap(), vec![1000]);
355
+        assert_eq!(intcode.clone().execute(9).unwrap(), vec![1001]);
356
+    }
259 357
 }