From b35d785d6965d8a1fc8a1022b719d2c57eac529d Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Wed, 14 Nov 2018 12:50:53 +0100 Subject: [PATCH] Implement day 23. Could use some optimization, but it works. --- 2016/inputs/23.txt | 26 ++++++++++++++ 2016/src/common.rs | 87 +++++++++++++++++++++++++++++++++------------- 2016/src/day23.rs | 49 ++++++++++++++++++++++++++ 2016/src/main.rs | 2 ++ 4 files changed, 140 insertions(+), 24 deletions(-) create mode 100644 2016/inputs/23.txt create mode 100644 2016/src/day23.rs diff --git a/2016/inputs/23.txt b/2016/inputs/23.txt new file mode 100644 index 0000000..25384ff --- /dev/null +++ b/2016/inputs/23.txt @@ -0,0 +1,26 @@ +cpy a b +dec b +cpy a d +cpy 0 a +cpy b c +inc a +dec c +jnz c -2 +dec d +jnz d -5 +dec b +cpy b c +cpy c d +dec d +inc c +jnz d -2 +tgl c +cpy -16 c +jnz 1 c +cpy 84 c +jnz 71 d +inc a +inc d +jnz d -2 +inc c +jnz c -5 diff --git a/2016/src/common.rs b/2016/src/common.rs index 0843bb7..2c95103 100644 --- a/2016/src/common.rs +++ b/2016/src/common.rs @@ -101,34 +101,73 @@ impl AssemBunnyCPU { let mut iptr: i32 = 0; while iptr < self.instructions.len() as i32 { - let ref instruction = self.instructions[iptr as usize]; - match instruction[0].as_ref() { - "cpy" => { - let val = self.get_value(&instruction[1]); - let dest = register_num(&instruction[2]).unwrap(); - self.registers[dest] = val; - }, - "jnz" => { - let val = self.get_value(&instruction[1]); - if val != 0 { - let jump: i32 = instruction[2].parse().unwrap(); - iptr += jump; - continue; - } - }, - "inc" => { - let dest = register_num(&instruction[1]).unwrap(); - self.registers[dest] += 1; - }, - "dec" => { - let dest = register_num(&instruction[1]).unwrap(); - self.registers[dest] -= 1; - }, - _ => panic!("Invalid instruction: {:?}", instruction), + let mut instruction_target = 0; + let mut new_instruction = Vec::new(); + { + let ref instruction = self.instructions[iptr as usize]; + match instruction[0].as_ref() { + "cpy" => { + let val = self.get_value(&instruction[1]); + match register_num(&instruction[2]) { + Some(num) => { self.registers[num] = val; }, + None => { + // Invalid instruction generated. + }, + } + }, + "jnz" => { + let val = self.get_value(&instruction[1]); + if val != 0 { + let jump: i32 = self.get_value(&instruction[2]); + iptr += jump; + continue; + } + }, + "inc" => { + match register_num(&instruction[1]) { + Some(num) => { self.registers[num] += 1 }, + None => { + // Invalid instruction generated. + }, + } + }, + "dec" => { + match register_num(&instruction[1]) { + Some(num) => { self.registers[num] -= 1; }, + None => { + // Invalid instruction generated. + }, + } + }, + "tgl" => { + instruction_target = (iptr + self.get_value(&instruction[1])) as usize; + if instruction_target < self.instructions.len() { + new_instruction = self.instructions[instruction_target].clone(); + new_instruction[0] = String::from(match new_instruction.len() { + 2 => match new_instruction[0].as_str() { + "inc" => "dec", + _ => "inc", + } + 3 => match new_instruction[0].as_str() { + "jnz" => "cpy", + _ => "jnz", + }, + _ => panic!("Cannot toggle instruction {}", instruction_target), + }); + } + }, + _ => panic!("Invalid instruction: {:?}", instruction), + } } iptr += 1; + + // Check if we need to override an instruction + if new_instruction.len() != 0 { + self.instructions[instruction_target] = new_instruction; + } } + self.get_value("a") } } diff --git a/2016/src/day23.rs b/2016/src/day23.rs new file mode 100644 index 0000000..35632c7 --- /dev/null +++ b/2016/src/day23.rs @@ -0,0 +1,49 @@ +use std::io; +use common; + +#[derive(Default)] +pub struct Day23 { + cpu: common::AssemBunnyCPU, +} + +impl Day23 { + pub fn new() -> Day23 { + Default::default() + } +} + +impl common::Solution for Day23 { + + fn part1(&mut self, input: &mut io::Read) -> String { + self.cpu.read_instructions(input); + self.cpu.registers[0] = 7; + format!("{}", self.cpu.run()) + } + + fn part2(&mut self, input: &mut io::Read) -> String { + self.cpu.read_instructions(input); + self.cpu.registers[0] = 12; + format!("{}", self.cpu.run()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use common::Solution; + + const SAMPLE_INPUT: &str = "cpy 2 a +tgl a +tgl a +tgl a +cpy 1 a +dec a +dec a"; + + #[test] + fn sample_part1() { + let mut instance = Day23::new(); + assert_eq!("3", instance.part1(&mut SAMPLE_INPUT.as_bytes())) + } + +} diff --git a/2016/src/main.rs b/2016/src/main.rs index 0cd4abe..92c98c0 100644 --- a/2016/src/main.rs +++ b/2016/src/main.rs @@ -10,6 +10,7 @@ pub mod day1; pub mod day12; pub mod day15; pub mod day16; +pub mod day23; fn get_impl(day: i32) -> Box { match day { @@ -17,6 +18,7 @@ fn get_impl(day: i32) -> Box { 12 => { Box::new(day12::Day12::new()) } 15 => { Box::new(day15::Day15::new()) } 16 => { Box::new(day16::Day16::new()) } + 23 => { Box::new(day23::Day23::new()) } _ => { panic!("Unimplemented day {}", day) }