advent-of-code

Perserverance, or the lack thereof

git clone git://git.shimmy1996.com/advent-of-code.git
commit 4452b2b72d241473adeab7773476091032cbee92
parent e4e7917ec3c60453d8900fa47833973dd8e53136
Author: Shimmy Xu <shimmy.xu@shimmy1996.com>
Date:   Mon,  9 Dec 2019 09:18:00 -0500

Add Rust solution for day 09

Diffstat:
Aday-09/Makefile | 9+++++++++
Aday-09/day-09.rs | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aday-09/input.txt | 1+
3 files changed, 156 insertions(+), 0 deletions(-)
diff --git a/day-09/Makefile b/day-09/Makefile
@@ -0,0 +1,9 @@
+CC := g++
+CCFLAGS := --std=c++17 -Wall
+
+all: day-09-rust day-09.jl
+	julia day-09.jl
+	./day-09-rust
+
+day-09-rust: day-09.rs
+	rustc $^ -o $@
diff --git a/day-09/day-09.rs b/day-09/day-09.rs
@@ -0,0 +1,146 @@
+use std::collections::HashMap;
+type Op = i128;
+
+fn main() {
+    let input = std::fs::read_to_string("input.txt")
+        .unwrap()
+        .trim()
+        .split(",")
+        .map(|op| op.parse::<Op>().unwrap())
+        .collect::<Vec<Op>>();
+    println!("Rust:");
+    println!("Part 1: {}", part_1(&input));
+    println!("Part 2: {}", part_2(&input));
+}
+
+fn computer(program: &Vec<Op>, input: Op) -> Vec<Op> {
+    // Use a hash table for more memory.
+    let mut program = program
+        .iter()
+        .enumerate()
+        .map(|(idx, &op)| (idx, op))
+        .collect::<HashMap<usize, Op>>();
+    let mut output = vec![];
+    let mut pc = 0;
+    let mut relative_base = 0;
+
+    let get_param = |loc: usize, mode, program: &HashMap<usize, Op>, relative_base| -> Op {
+        match mode {
+            // Position mode.
+            0 => *program.get(&(program[&loc] as usize)).unwrap_or(&0),
+            // Immediate mode.
+            1 => program[&loc],
+            // Relative mode.
+            2 => *program
+                .get(&((relative_base + program[&loc]) as usize))
+                .unwrap_or(&0),
+            _ => panic!(),
+        }
+    };
+
+    let get_res_loc =
+        |loc: usize, mode, program: &HashMap<usize, Op>, relative_base: i128| -> usize {
+            match mode {
+                // Position mode.
+                0 => program[&loc] as usize,
+                // Immediate mode is banned.
+                // Relative mode.
+                2 => (relative_base + program[&loc]) as usize,
+                _ => panic!(),
+            }
+        };
+
+    loop {
+        let op_code = program[&pc] % 100;
+        let mode_1 = (program[&pc] % 1000) / 100;
+        let mode_2 = (program[&pc] % 10000) / 1000;
+        let mode_3 = (program[&pc] % 100000) / 10000;
+        // Third parameter is location to write to, and will never be immediate
+        // mode.
+        match op_code {
+            1 => {
+                let res_loc = get_res_loc(pc + 3, mode_3, &program, relative_base);
+                let param_1 = get_param(pc + 1, mode_1, &program, relative_base);
+                let param_2 = get_param(pc + 2, mode_2, &program, relative_base);
+                *program.entry(res_loc).or_default() = param_1 + param_2;
+                pc += 4;
+            }
+            2 => {
+                let res_loc = get_res_loc(pc + 3, mode_3, &program, relative_base);
+                let param_1 = get_param(pc + 1, mode_1, &program, relative_base);
+                let param_2 = get_param(pc + 2, mode_2, &program, relative_base);
+                *program.entry(res_loc as usize).or_default() = param_1 * param_2;
+                pc += 4;
+            }
+            3 => {
+                let res_loc = get_res_loc(pc + 1, mode_1, &program, relative_base);
+                *program.entry(res_loc as usize).or_default() = input;
+                pc += 2;
+            }
+            4 => {
+                let param_1 = get_param(pc + 1, mode_1, &program, relative_base);
+                output.push(param_1);
+                pc += 2;
+            }
+            5 => {
+                let param_1 = get_param(pc + 1, mode_1, &program, relative_base);
+                let param_2 = get_param(pc + 2, mode_2, &program, relative_base);
+                if param_1 != 0 {
+                    pc = param_2 as usize;
+                } else {
+                    pc += 3;
+                }
+            }
+            6 => {
+                let param_1 = get_param(pc + 1, mode_1, &program, relative_base);
+                let param_2 = get_param(pc + 2, mode_2, &program, relative_base);
+                if param_1 == 0 {
+                    pc = param_2 as usize;
+                } else {
+                    pc += 3;
+                }
+            }
+            7 => {
+                let res_loc = get_res_loc(pc + 3, mode_3, &program, relative_base);
+                let param_1 = get_param(pc + 1, mode_1, &program, relative_base);
+                let param_2 = get_param(pc + 2, mode_2, &program, relative_base);
+                *program.entry(res_loc as usize).or_default() =
+                    if param_1 < param_2 { 1 } else { 0 };
+                pc += 4;
+            }
+            8 => {
+                let res_loc = get_res_loc(pc + 3, mode_3, &program, relative_base);
+                let param_1 = get_param(pc + 1, mode_1, &program, relative_base);
+                let param_2 = get_param(pc + 2, mode_2, &program, relative_base);
+                *program.entry(res_loc as usize).or_default() =
+                    if param_1 == param_2 { 1 } else { 0 };
+                pc += 4;
+            }
+            9 => {
+                let param_1 = get_param(pc + 1, mode_1, &program, relative_base);
+                relative_base += param_1;
+                pc += 2;
+            }
+            99 => {
+                break;
+            }
+            _ => {
+                println!("Unknown op {}", op_code);
+                println!("{}", program[&pc]);
+                panic!();
+            }
+        }
+    }
+
+    output
+}
+
+fn part_1(input: &Vec<Op>) -> i128 {
+    let output = computer(input, 1);
+    *output.last().unwrap()
+}
+
+fn part_2(input: &Vec<Op>) -> i128 {
+    let output = computer(input, 2);
+    *output.last().unwrap()
+}
diff --git a/day-09/input.txt b/day-09/input.txt
@@ -0,0 +1 @@
+1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1101,3,0,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1102,1,31,1008,1101,682,0,1027,1101,0,844,1029,1102,29,1,1001,1102,1,22,1014,1101,0,21,1011,1102,428,1,1025,1101,0,433,1024,1101,0,38,1019,1102,1,37,1016,1102,35,1,1017,1102,39,1,1018,1102,32,1,1000,1102,23,1,1012,1102,1,329,1022,1102,26,1,1006,1102,1,24,1003,1102,28,1,1005,1102,36,1,1010,1102,34,1,1004,1101,0,1,1021,1102,326,1,1023,1101,33,0,1015,1101,20,0,1002,1101,0,25,1007,1101,0,853,1028,1102,27,1,1009,1102,1,30,1013,1101,689,0,1026,1102,1,0,1020,109,12,2108,30,-3,63,1005,63,201,1001,64,1,64,1105,1,203,4,187,1002,64,2,64,109,-9,2101,0,6,63,1008,63,29,63,1005,63,227,1001,64,1,64,1106,0,229,4,209,1002,64,2,64,109,-6,1208,5,22,63,1005,63,249,1001,64,1,64,1106,0,251,4,235,1002,64,2,64,109,13,21107,40,41,8,1005,1018,273,4,257,1001,64,1,64,1105,1,273,1002,64,2,64,109,-11,2102,1,8,63,1008,63,25,63,1005,63,299,4,279,1001,64,1,64,1105,1,299,1002,64,2,64,109,15,1205,7,317,4,305,1001,64,1,64,1105,1,317,1002,64,2,64,109,10,2105,1,-1,1105,1,335,4,323,1001,64,1,64,1002,64,2,64,109,-22,1202,1,1,63,1008,63,24,63,1005,63,357,4,341,1106,0,361,1001,64,1,64,1002,64,2,64,109,13,1206,6,373,1106,0,379,4,367,1001,64,1,64,1002,64,2,64,109,11,1206,-6,393,4,385,1105,1,397,1001,64,1,64,1002,64,2,64,109,-32,1208,10,34,63,1005,63,419,4,403,1001,64,1,64,1105,1,419,1002,64,2,64,109,30,2105,1,0,4,425,1106,0,437,1001,64,1,64,1002,64,2,64,109,-28,1207,6,21,63,1005,63,455,4,443,1106,0,459,1001,64,1,64,1002,64,2,64,109,4,2101,0,8,63,1008,63,31,63,1005,63,485,4,465,1001,64,1,64,1105,1,485,1002,64,2,64,109,5,1207,-4,28,63,1005,63,505,1001,64,1,64,1106,0,507,4,491,1002,64,2,64,109,9,21102,41,1,2,1008,1016,39,63,1005,63,531,1001,64,1,64,1106,0,533,4,513,1002,64,2,64,109,-10,1201,4,0,63,1008,63,30,63,1005,63,553,1106,0,559,4,539,1001,64,1,64,1002,64,2,64,109,19,21108,42,41,-4,1005,1019,579,1001,64,1,64,1106,0,581,4,565,1002,64,2,64,109,-26,1201,3,0,63,1008,63,32,63,1005,63,607,4,587,1001,64,1,64,1106,0,607,1002,64,2,64,109,20,1205,3,623,1001,64,1,64,1105,1,625,4,613,1002,64,2,64,109,2,21107,43,42,-1,1005,1018,645,1001,64,1,64,1106,0,647,4,631,1002,64,2,64,109,-11,2102,1,1,63,1008,63,29,63,1005,63,667,1105,1,673,4,653,1001,64,1,64,1002,64,2,64,109,27,2106,0,-8,1001,64,1,64,1105,1,691,4,679,1002,64,2,64,109,-25,2107,25,-4,63,1005,63,713,4,697,1001,64,1,64,1105,1,713,1002,64,2,64,109,-2,21108,44,44,2,1005,1010,735,4,719,1001,64,1,64,1106,0,735,1002,64,2,64,109,11,21101,45,0,-3,1008,1016,45,63,1005,63,757,4,741,1106,0,761,1001,64,1,64,1002,64,2,64,109,-15,1202,3,1,63,1008,63,22,63,1005,63,781,1105,1,787,4,767,1001,64,1,64,1002,64,2,64,109,6,21101,46,0,0,1008,1010,49,63,1005,63,811,1001,64,1,64,1105,1,813,4,793,1002,64,2,64,109,-7,2108,34,1,63,1005,63,835,4,819,1001,64,1,64,1105,1,835,1002,64,2,64,109,15,2106,0,10,4,841,1001,64,1,64,1106,0,853,1002,64,2,64,109,-25,2107,33,7,63,1005,63,873,1001,64,1,64,1106,0,875,4,859,1002,64,2,64,109,7,21102,47,1,10,1008,1010,47,63,1005,63,897,4,881,1105,1,901,1001,64,1,64,4,64,99,21102,1,27,1,21102,915,1,0,1105,1,922,21201,1,12038,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21102,942,1,0,1105,1,922,21202,1,1,-1,21201,-2,-3,1,21101,0,957,0,1106,0,922,22201,1,-1,-2,1106,0,968,22101,0,-2,-2,109,-3,2105,1,0