diff --git a/2016/day-12/Cargo.toml b/2016/day-12/Cargo.toml deleted file mode 100644 index 64568fb..0000000 --- a/2016/day-12/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "day-12" -version = "0.1.0" -authors = ["Bert Peters "] - -[dependencies] diff --git a/2016/day-12/src/main.rs b/2016/day-12/src/main.rs deleted file mode 100644 index 324d86e..0000000 --- a/2016/day-12/src/main.rs +++ /dev/null @@ -1,81 +0,0 @@ -use std::env; -use std::io::prelude::*; -use std::fs::File; -use std::io::BufReader; - -fn register_num(value: &str) -> Option -{ - match value { - "a" => Some(0), - "b" => Some(1), - "c" => Some(2), - "d" => Some(3), - _ => None, - } -} - -fn get_value(value: &str, registers: &[i32; 4]) -> i32 -{ - match register_num(value) { - Some(num) => registers[num], - _ => value.parse().unwrap(), - } -} - -fn run(program: &Vec>, mut registers: [i32; 4]) -> [i32; 4] -{ - let mut iptr: i32 = 0; - - while iptr < program.len() as i32 { - let ref instruction = program[iptr as usize]; - //println!("{} ({:?}): {:?}", iptr, registers, instruction); - match instruction[0].as_ref() { - "cpy" => { - let val = get_value(&instruction[1], ®isters); - let dest = register_num(&instruction[2]).unwrap(); - registers[dest] = val; - }, - "jnz" => { - let val = get_value(&instruction[1], ®isters); - if val != 0 { - let jump: i32 = instruction[2].parse().unwrap(); - iptr += jump; - continue; - } - }, - "inc" => { - let dest = register_num(&instruction[1]).unwrap(); - registers[dest] += 1; - }, - "dec" => { - let dest = register_num(&instruction[1]).unwrap(); - registers[dest] -= 1; - }, - _ => panic!("Invalid instruction: {:?}", instruction), - } - iptr += 1; - } - - return registers; -} - -fn main() { - let args: Vec = env::args().collect(); - let f = File::open(&args[1]).expect("Could not open file"); - let reader = BufReader::new(f); - - let mut program = Vec::new(); - - for line in reader.lines() { - let contents = line.unwrap(); - let parts: Vec = contents.split(" ").map(|part| String::from(part)).collect(); - - program.push(parts); - } - - let result1 = run(&program, [0; 4]); - println!("Run 1: register a contains {}", result1[0]); - - let result2 = run(&program, [0, 0, 1, 0]); - println!("Run 2: register a contains {}", result2[0]); -} diff --git a/2016/day-12/input.txt b/2016/inputs/12.txt similarity index 100% rename from 2016/day-12/input.txt rename to 2016/inputs/12.txt diff --git a/2016/src/common.rs b/2016/src/common.rs index fe1ed30..0843bb7 100644 --- a/2016/src/common.rs +++ b/2016/src/common.rs @@ -1,6 +1,7 @@ use std::io; use std::ops; use std::cmp; +use std::io::prelude::*; /// Apply Erathostenes's sieve to the supplied array /// @@ -61,6 +62,77 @@ pub trait Solution { fn part2(&mut self, input: &mut io::Read) -> String; } +#[derive(Default)] +pub struct AssemBunnyCPU { + instructions: Vec>, + pub registers: [i32; 4] +} + +fn register_num(value: &str) -> Option +{ + match value { + "a" => Some(0), + "b" => Some(1), + "c" => Some(2), + "d" => Some(3), + _ => None, + } +} + +impl AssemBunnyCPU { + fn get_value(&self, value: &str) -> i32 { + match register_num(value) { + Some(num) => self.registers[num], + None => value.parse().unwrap() + } + } + + pub fn read_instructions(&mut self, input: &mut io::Read) { + let reader = io::BufReader::new(input); + for line in reader.lines() { + let contents = line.unwrap(); + let parts: Vec = contents.split(" ").map(|part| String::from(part)).collect(); + + self.instructions.push(parts); + } + } + + pub fn run(&mut self)-> i32 { + 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), + } + iptr += 1; + } + + self.get_value("a") + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/2016/src/day12.rs b/2016/src/day12.rs new file mode 100644 index 0000000..697e19c --- /dev/null +++ b/2016/src/day12.rs @@ -0,0 +1,47 @@ +use std::io; +use common; + +#[derive(Default)] +pub struct Day12 { + cpu: common::AssemBunnyCPU, +} + +impl Day12 { + pub fn new() -> Day12 { + Default::default() + } +} + +impl common::Solution for Day12 { + + fn part1(&mut self, input: &mut io::Read) -> String { + self.cpu.read_instructions(input); + format!("{}", self.cpu.run()) + } + + fn part2(&mut self, input: &mut io::Read) -> String { + self.cpu.read_instructions(input); + self.cpu.registers[2] = 1; + format!("{}", self.cpu.run()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use common::Solution; + + const SAMPLE_INPUT: &str = "cpy 41 a +inc a +inc a +dec a +jnz a 2 +dec a"; + + #[test] + fn sample_part1() { + let mut instance = Day12::new(); + assert_eq!("42", instance.part1(&mut SAMPLE_INPUT.as_bytes())) + } + +} diff --git a/2016/src/main.rs b/2016/src/main.rs index 5d34b92..0cd4abe 100644 --- a/2016/src/main.rs +++ b/2016/src/main.rs @@ -7,12 +7,14 @@ use std::io; pub mod common; pub mod day1; +pub mod day12; pub mod day15; pub mod day16; fn get_impl(day: i32) -> Box { match day { 1 => { Box::new(day1::Day1::new()) } + 12 => { Box::new(day12::Day12::new()) } 15 => { Box::new(day15::Day15::new()) } 16 => { Box::new(day16::Day16::new()) } _ => {