extern crate advent_of_code_2018; use advent_of_code_2018::*; use std::error::Error; 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); }