diff --git a/src/days.rs b/src/days.rs index 1c4b09e..bae5f25 100644 --- a/src/days.rs +++ b/src/days.rs @@ -9,7 +9,7 @@ pub mod d8; pub mod d9; pub mod d10; pub mod d11; -// pub mod d12; +pub mod d12; // pub mod d13; // pub mod d14; // pub mod d15; diff --git a/src/days/d12.rs b/src/days/d12.rs new file mode 100644 index 0000000..c1c303c --- /dev/null +++ b/src/days/d12.rs @@ -0,0 +1,121 @@ +use crate::prelude::*; + +pub type I = Vec; +pub type O = i64; + +pub enum Val { + Register (char), + Literal (i64), +} + + +#[allow(dead_code)] +impl Val { + fn new (i: &str) -> Self { + match i.parse::() { + Ok(s) => Self::Literal(s), + Err(_) => Self::Register(i.chars().next().unwrap()) + } + } +} + +pub enum Inst { + Jnz (Val, isize), + Cpy (Val, char), + Inc (char), + Dec (char) +} + + + +fn _parse (data: &str) -> I { + data.trim().lines().map(|line| { + let mut split = line.split_ascii_whitespace(); + match split.next().unwrap() { + "jnz" => { + Inst::Jnz(Val::new(split.next().unwrap()), split.next().unwrap().parse().unwrap()) + }, + "cpy" => { + Inst::Cpy(Val::new(split.next().unwrap()), split.next().unwrap().chars().next().unwrap()) + }, + "inc" => { + Inst::Inc(split.next().unwrap().chars().next().unwrap()) + }, + "dec" => { + Inst::Dec(split.next().unwrap().chars().next().unwrap()) + }, + _ => unreachable!() + } + }).collect() +} + +fn _solve (data: I, r: &mut M) { + let mut ptr = 0; + + while ptr < data.len() { + let i = &data[ptr]; + + match i { + Inst::Inc(reg) => *r.entry(*reg).or_default() += 1, + Inst::Dec(reg) => *r.entry(*reg).or_default() -= 1, + Inst::Cpy(val, reg) => { + match val { + Val::Literal(val) => *r.entry(*reg).or_default() = *val, + Val::Register(r2) => *r.entry(*reg).or_default() = *r.get(r2).unwrap(), + } + }, + Inst::Jnz(val, dest) => { + let val = match val { + Val::Literal(val) => *val, + Val::Register(r2) => *r.get(r2).unwrap(), + }; + + if val != 0 { + ptr = ptr.checked_add_signed(*dest).unwrap_or(0); + continue; + } + + } + + } + ptr += 1; + } +} + +fn _silver (data: I) -> O { + let mut state = M::from([('a', 0), ('b', 0), ('c', 0), ('d', 0)]); + _solve(data, &mut state); + *state.get(&'a').unwrap() +} + +fn _gold (data: I) -> O { + let mut state = M::from([('a', 0), ('b', 0), ('c', 1), ('d', 0)]); + _solve(data, &mut state); + *state.get(&'a').unwrap() +} + +#[cfg(test)] +mod test { + use super::*; + + fn read () -> I { + let data = inc!(12); + _parse(data) + } + + #[test] + fn silver () { + let data = read(); + let ans = _silver(data); + + assert_eq!(ans, 318007) + } + + #[test] + fn gold () { + let data = read(); + let ans = _gold(data); + + assert_eq!(ans, 9227661) + } +}