Day 19: Disassembler
authorJustin Worthe <justin@worthe-it.co.za>
Wed, 19 Dec 2018 18:58:15 +0000 (20:58 +0200)
committerJustin Worthe <justin@worthe-it.co.za>
Wed, 19 Dec 2018 18:58:15 +0000 (20:58 +0200)
inputs/19.txt [new file with mode: 0644]
src/bin/day_19.rs

diff --git a/inputs/19.txt b/inputs/19.txt
new file mode 100644 (file)
index 0000000..1207b7b
--- /dev/null
@@ -0,0 +1,37 @@
+#ip 4
+addi 4 16 4
+seti 1 7 2
+seti 1 1 5
+mulr 2 5 3
+eqrr 3 1 3
+addr 3 4 4
+addi 4 1 4
+addr 2 0 0
+addi 5 1 5
+gtrr 5 1 3
+addr 4 3 4
+seti 2 7 4
+addi 2 1 2
+gtrr 2 1 3
+addr 3 4 4
+seti 1 3 4
+mulr 4 4 4
+addi 1 2 1
+mulr 1 1 1
+mulr 4 1 1
+muli 1 11 1
+addi 3 3 3
+mulr 3 4 3
+addi 3 9 3
+addr 1 3 1
+addr 4 0 4
+seti 0 1 4
+setr 4 9 3
+mulr 3 4 3
+addr 4 3 3
+mulr 4 3 3
+muli 3 14 3
+mulr 3 4 3
+addr 1 3 1
+seti 0 6 0
+seti 0 7 4
index 398394d..37ffef1 100644 (file)
@@ -6,13 +6,134 @@ use std::path::PathBuf;
 
 // cargo watch -cs "cargo run --release --bin day_19"
 
+#[derive(Debug)]
+struct Instruction {
+    op: Op,
+    a: i32,
+    b: i32,
+    c: i32
+}
+
+impl Instruction {
+    fn execute(&self, counter_register: usize, registers: &mut [i32; 6]) -> i32{
+        use Op::*;
+        
+        registers[self.c as usize] = match self.op {
+            Addr => registers[self.a as usize] + registers[self.b as usize],
+            Addi => registers[self.a as usize] + self.b,
+            Mulr => registers[self.a as usize] * registers[self.b as usize],
+            Muli => registers[self.a as usize] * self.b,
+            Banr => registers[self.a as usize] & registers[self.b as usize],
+            Bani => registers[self.a as usize] & self.b,
+            Borr => registers[self.a as usize] | registers[self.b as usize],
+            Bori => registers[self.a as usize] | self.b,
+            Setr => registers[self.a as usize],
+            Seti => self.a,
+            Gtir => if self.a > registers[self.b as usize] { 1 } else { 0 },
+            Gtri => if registers[self.a as usize] > self.b { 1 } else { 0 },
+            Gtrr => if registers[self.a as usize] > registers[self.b as usize] { 1 } else { 0 },
+            Eqir => if self.a == registers[self.b as usize] { 1 } else { 0 },
+            Eqri => if registers[self.a as usize] == self.b { 1 } else { 0 },
+            Eqrr => if registers[self.a as usize] == registers[self.b as usize] { 1 } else { 0 },
+        };
+
+        registers[counter_register]+1
+    }
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+enum Op {
+    Addr,
+    Addi,
+    Mulr,
+    Muli,
+    Banr,
+    Bani,
+    Borr,
+    Bori,
+    Setr,
+    Seti,
+    Gtir,
+    Gtri,
+    Gtrr,
+    Eqir,
+    Eqri,
+    Eqrr
+}
+
 fn main() -> Result<(), Box<Error>> {
     let input = read_file(&PathBuf::from("inputs/19.txt"))?;
 
     println!("Input: {:?}", input);
 
+    let mut input_iter = input.iter();
+    let counter_register: usize = input_iter.next()
+        .map(|line| line.split_whitespace().nth(1).unwrap().parse().unwrap())
+        .unwrap();
+
+    let instructions: Vec<Instruction> = input_iter
+        .map(|line| {
+            let mut instruction_iter = line.split_whitespace();
+            Instruction {
+                op: match instruction_iter.next().unwrap() {
+                    "addr" => Op::Addr,
+                    "addi" => Op::Addi,
+                    "mulr" => Op::Mulr,
+                    "muli" => Op::Muli,
+                    "banr" => Op::Banr,
+                    "bani" => Op::Bani,
+                    "borr" => Op::Borr,
+                    "bori" => Op::Bori,
+                    "setr" => Op::Setr,
+                    "seti" => Op::Seti,
+                    "gtir" => Op::Gtir,
+                    "gtri" => Op::Gtri,
+                    "gtrr" => Op::Gtrr,
+                    "eqir" => Op::Eqir,
+                    "eqri" => Op::Eqri,
+                    "eqrr" => Op::Eqrr,
+                    _ => panic!("unknown instruction")
+                },
+                a: instruction_iter.next().unwrap().parse().unwrap(),
+                b: instruction_iter.next().unwrap().parse().unwrap(),
+                c: instruction_iter.next().unwrap().parse().unwrap(),
+            }
+        })
+        .collect();
 
+    debug!(counter_register);
+    debug!(instructions);
 
+    let part1_registers = execute_program(&instructions, counter_register, [0; 6]);
+    debug!(part1_registers);
 
+    //let part2_registers = execute_program(&instructions, counter_register, [1, 0, 0, 0, 0, 0]);
+    //debug!(part2_registers);
+    part2();
+    
     Ok(())
 }
+
+fn execute_program(instructions: &Vec<Instruction>, counter_register: usize, registers: [i32; 6]) -> [i32; 6] {
+    let mut counter_val: i32 = 0;
+    let mut registers = registers.clone();
+    while counter_val >= 0 && counter_val < instructions.len() as i32 {
+        registers[counter_register] = counter_val;
+        counter_val = instructions[counter_val as usize].execute(counter_register, &mut registers);
+    }
+
+    registers
+}
+
+
+
+fn part2() {
+    let r1 = ((27*28)+29)*30*14*32 + (11 * 19 * 2 * 2) + (3 * 22) + 9;
+    let mut r0 = 0;
+    for r5 in 1..r1+1 {
+        if r1 % r5 == 0 {
+            r0 += r1 / r5;
+        }
+    }
+    debug!(r0);
+}