diff --git a/2016/input/day_12.txt b/2016/input/day_12.txt new file mode 100644 index 0000000..8084c18 --- /dev/null +++ b/2016/input/day_12.txt @@ -0,0 +1,23 @@ +cpy 1 a +cpy 1 b +cpy 26 d +jnz c 2 +jnz 1 5 +cpy 7 c +inc d +dec c +jnz c -2 +cpy a c +inc a +dec b +jnz b -2 +cpy c b +dec d +jnz d -6 +cpy 16 c +cpy 17 d +inc a +dec d +jnz d -2 +dec c +jnz c -5 \ No newline at end of file diff --git a/2016/rust/src/day_12.rs b/2016/rust/src/day_12.rs new file mode 100644 index 0000000..b7827c8 --- /dev/null +++ b/2016/rust/src/day_12.rs @@ -0,0 +1,98 @@ +use std::collections::HashMap; + +use errors::*; + +pub fn solve(input: &str) -> Result { + Ok("".into()) +} + +// The assembunny code you've extracted operates on four registers (a, b, c, and d) that start at 0 +// and can hold any integer. However, it seems to make use of only a few instructions: +#[derive(Clone, Debug, Hash, Eq, PartialEq)] +enum Register { + A, + B, + C, + D, +} + +enum Variable { + Register(Register), + Value(usize), +} + +#[derive(Debug, PartialEq)] +struct State { + pc: usize, + registers: HashMap, +} + +impl State { + fn value(&self, v: &Variable) -> isize { + match v { + &Variable::Register(ref r) => { + self.registers.get(r).cloned().unwrap_or(0 as isize) + } + &Variable::Value(value) => value as isize, + } + } +} + +// cpy x y copies x (either an integer or the value of a register) into register y. +struct Copy { + variable: Variable, + register: Register, +} + +impl Copy { + fn run(&self, state: &State) -> State { + let pc = state.pc + 1; + let value = state.value(&self.variable); + let mut registers = state.registers.clone(); + registers.insert(self.register.clone(), value); + State { + pc: pc, + registers: registers, + } + } +} + +// inc x increases the value of register x by one. +// dec x decreases the value of register x by one. +// jnz x y jumps to an instruction y away (positive means forward; negative means backward), but only if x is not zero. + +#[cfg(test)] +mod tests { + use super::{Variable, Register, State, Copy}; + + #[test] + fn test_state_value() { + let state = State { + pc: 0, + registers: vec![(Register::A, 41)].into_iter().collect(), + }; + assert_eq!(state.value(&Variable::Register(Register::A)), 41); + assert_eq!(state.value(&Variable::Register(Register::B)), 0); + assert_eq!(state.value(&Variable::Value(23)), 23); + } + + #[test] + fn test_copy() { + let variable = Variable::Value(41); + let register = Register::A; + let copy = Copy { + variable: variable, + register: register, + }; + let state = State { + pc: 0, + registers: vec![].into_iter().collect(), + }; + let expected = State { + pc: 1, + registers: vec![(Register::A, 41)].into_iter().collect(), + }; + + assert_eq!(copy.run(&state), expected); + } +} diff --git a/2016/rust/src/lib.rs b/2016/rust/src/lib.rs index ba7f4b3..8963715 100644 --- a/2016/rust/src/lib.rs +++ b/2016/rust/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(inclusive_range_syntax)] +#![feature(field_init_shorthand, inclusive_range_syntax)] #![recursion_limit = "1024"] #[macro_use] @@ -15,5 +15,6 @@ pub mod day_05; pub mod day_06; pub mod day_07; pub mod day_08; -pub mod day_09; +// pub mod day_09; // pub mod day_10; +pub mod day_12; diff --git a/2016/rust/src/main.rs b/2016/rust/src/main.rs index b7f73a8..27be66b 100644 --- a/2016/rust/src/main.rs +++ b/2016/rust/src/main.rs @@ -10,7 +10,7 @@ fn main() { let mut input = String::new(); io::stdin().read_to_string(&mut input).ok(); - let solution = day_09::solve(&input)?; + let solution = day_12::solve(&input)?; println!("{}", solution); Ok(())