From 98302af8c17f2614e5c32ec2ad465fc7cae27ce3 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Wed, 19 Dec 2018 20:58:15 +0200 Subject: Day 19: Disassembler --- src/bin/day_19.rs | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) (limited to 'src') diff --git a/src/bin/day_19.rs b/src/bin/day_19.rs index 398394d..37ffef1 100644 --- a/src/bin/day_19.rs +++ b/src/bin/day_19.rs @@ -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> { 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 = 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, 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); +} -- cgit v1.2.3