Day 05
authorGrégory Burri <gregory.burri@matisa.ch>
Mon, 9 Dec 2019 13:54:35 +0000 (14:54 +0100)
committerGrégory Burri <gregory.burri@matisa.ch>
Mon, 9 Dec 2019 13:54:35 +0000 (14:54 +0100)
src/day05.rs
src/main.rs

index 1ff5739..61f6203 100644 (file)
-fn read_code(code: i32) -> (i32, Vec<bool>) {\r
+// 'true' -> immediate mode, 'false' -> position mode.\r
+fn read_op_and_modes(mut code: i32) -> (i32, [bool; 3]) {\r
+    let mut modes: [bool; 3] = [ false, false, false ];\r
 \r
+    if code >= 10_000 {\r
+        modes[2] = true;\r
+        code -= 10_000;\r
+    }\r
+\r
+    if code >= 1_000 {\r
+        modes[1] = true;\r
+        code -= 1_000;\r
+    }\r
+\r
+    if code >= 100 {\r
+        modes[0] = true;\r
+        code -= 100;\r
+    }\r
+\r
+    (code, modes)\r
 }\r
 \r
-fn execute_op_code(code: &mut [i32], input: &[i32]) -> Vec<i32> {\r
+pub fn execute_op_code(code: &mut [i32], input: &[i32]) -> Vec<i32> {\r
     let mut cursor = 0;\r
+    let mut input_cursor = 0;\r
     let mut output = Vec::<i32>::new();\r
+\r
+    fn read(position: usize, code: &[i32], mode: bool) -> i32 {\r
+        if mode { code[position] } else { code[code[position] as usize] }\r
+    };\r
+\r
+    fn jump_if(cond: bool, cursor: usize, code: &[i32], modes: [bool; 3]) -> usize {\r
+        let value = read(cursor + 1, &code, modes[0]);\r
+        if cond == (value != 0) {\r
+            read(cursor + 2, &code, modes[1]) as usize\r
+        } else {\r
+            cursor + 3\r
+        }\r
+    };\r
+\r
     loop {\r
-        match code[cursor] {\r
-            1 => code[code[cursor + 3] as usize] = code[code[cursor + 1] as usize] + code[code[cursor + 2] as usize],\r
-            2 => code[code[cursor + 3] as usize] = code[code[cursor + 1] as usize] * code[code[cursor + 2] as usize],\r
-            99 => return code[0],\r
+        let (op, modes) = read_op_and_modes(code[cursor]);\r
+\r
+        match op {\r
+            // Sum.\r
+            1 => {\r
+                code[code[cursor + 3] as usize] = read(cursor + 1, &code, modes[0]) + read(cursor + 2, &code, modes[1]);\r
+                cursor += 4;\r
+            },\r
+\r
+            // Multiply.\r
+            2 => {\r
+                code[code[cursor + 3] as usize] = read(cursor + 1, &code, modes[0]) * read(cursor + 2, &code, modes[1]);\r
+                cursor += 4;\r
+            },\r
+\r
+            // Input.\r
+            3 => {\r
+                code[code[cursor + 1] as usize] = input[input_cursor];\r
+                input_cursor += 1;\r
+                cursor += 2;\r
+            }\r
+\r
+            // Output.\r
+            4 => {\r
+                output.push(read(cursor + 1, &code, modes[0]));\r
+                cursor += 2;\r
+            }\r
+\r
+            // Jump-if-true.\r
+            5 => cursor = jump_if(true, cursor, &code, modes),\r
+\r
+            // Jump-if-false.\r
+            6 => cursor = jump_if(false, cursor, &code, modes),\r
+\r
+            // Less than.\r
+            7 => {\r
+                code[code[cursor + 3] as usize] =\r
+                    if read(cursor + 1, &code, modes[0]) < read(cursor + 2, &code, modes[1]) { 1 } else { 0 };\r
+                cursor += 4;\r
+            },\r
+\r
+            // Equals.\r
+            8 => {\r
+                code[code[cursor + 3] as usize] =\r
+                    if read(cursor + 1, &code, modes[0]) == read(cursor + 2, &code, modes[1]) { 1 } else { 0 };\r
+                cursor += 4;\r
+            },\r
+\r
+            99 => break,\r
             _ => panic!("Unkown code: {}", code[cursor])\r
         }\r
-        cursor += 4;\r
     }\r
+    output\r
 }\r
 \r
-\r
-\r
-\r
 #[cfg(test)]\r
 mod tests {\r
     use super::*;\r
 \r
     #[test]\r
     fn part1() {\r
+        let mut c = [1002, 4, 3, 4, 33];\r
+        let _ = execute_op_code(&mut c, &Vec::new());\r
+        assert_eq!(c[4], 99);\r
     }\r
 \r
     #[test]\r
     fn part2() {\r
+        let c = [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];\r
+\r
+        let mut c1 = c;\r
+        let r1 = execute_op_code(&mut c1, &[7]);\r
+        assert_eq!(r1[0], 999);\r
+\r
+        let mut c2 = c;\r
+        let r2 = execute_op_code(&mut c2, &[8]);\r
+        assert_eq!(r2[0], 1000);\r
+\r
+        let mut c3 = c;\r
+        let r3 = execute_op_code(&mut c3, &[9]);\r
+        assert_eq!(r3[0], 1001);\r
     }\r
 }
\ No newline at end of file
index d0dbfc3..eaccb71 100644 (file)
@@ -29,6 +29,15 @@ fn day03() -> String {
     )
 }
 
+fn day04() -> String {
+    format!("")
+}
+
+fn day05() -> String {
+    let code = common::read_list_of_numbers("data/day05.input", ",");
+    format!("part1: {:?}, part2: {:?}", day05::execute_op_code(&mut Vec::from(&code[..]), &[1]), day05::execute_op_code(&mut Vec::from(&code[..]), &[5]))
+}
+
 fn day06() -> String {
     let file_content = fs::read_to_string("data/day06.input").unwrap();
     let lines: Vec<&str> = file_content.lines().collect();
@@ -58,6 +67,8 @@ fn main() {
         day01,
         day02,
         day03,
+        day04,
+        day05,
         day06
     );