From 25844ee408f73893175a8dc999391df0a3ed377a Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Sat, 22 Dec 2018 01:00:42 +0100 Subject: Day 21 --- 2018/src/day21.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2018/src/device.rs | 2 +- 2018/src/main.rs | 4 +++- 3 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 2018/src/day21.rs (limited to '2018/src') diff --git a/2018/src/day21.rs b/2018/src/day21.rs new file mode 100644 index 0000000..e0983a3 --- /dev/null +++ b/2018/src/day21.rs @@ -0,0 +1,68 @@ +use std::io; +use std::io::BufRead; +use std::collections::HashSet; +use crate::device::*; + +#[allow(dead_code)] +fn optimise(mut instrs: Vec, ip_reg: usize) -> Vec { + for i in 0..instrs.len() { + instrs[i].inline_reg(ip_reg, Oper::Num(i)); + } + + instrs +} + +#[allow(dead_code)] +fn run_program(instrs: &[Instr], r0: usize, ip_reg: usize) -> usize { + let mut m = Machine { regs: [r0, 0, 0, 0, 0, 0] }; + m.exec_program(&instrs, ip_reg); + m.regs[0] +} + +pub fn main(reader: T) -> io::Result<(String, String)> { + let (ip_reg, instrs) = parse_program(reader)?; + + let instrs = optimise(instrs, ip_reg); + + // for instr in &instrs { println!("{}", instr); } + + let part1; + + let mut ip = 0; + let mut m = Machine { regs: [0, 0, 0, 0, 0, 0] }; + loop { + assert!(ip < instrs.len()); + if ip == 28 { + part1 = m.regs[4]; + break; + } + m.regs[ip_reg] = ip; + m.exec(&instrs[ip]); + ip = m.regs[ip_reg] + 1; + } + + let mut part2 = None; + + let mut seen_machines = HashSet::new(); + let mut seen_values = HashSet::new(); + + loop { + assert!(ip < instrs.len()); + if ip == 28 { + // println!("{:?}", m); + if seen_machines.contains(&m) { + break; + } + seen_machines.insert(m.clone()); + if !seen_values.contains(&m.regs[4]) { + part2 = Some(m.regs[4]); + seen_values.insert(m.regs[4]); + } + } + m.regs[ip_reg] = ip; + m.exec(&instrs[ip]); + ip = m.regs[ip_reg] + 1; + } + + Ok((part1.to_string(), part2.unwrap().to_string())) +} diff --git a/2018/src/device.rs b/2018/src/device.rs index 7eaf8d3..cf6d94e 100644 --- a/2018/src/device.rs +++ b/2018/src/device.rs @@ -181,7 +181,7 @@ impl fmt::Display for Instr { } } -#[derive(PartialEq, Eq, Clone)] +#[derive(PartialEq, Eq, Clone, Hash, Debug)] pub struct Machine { pub regs: [usize; 6], } diff --git a/2018/src/main.rs b/2018/src/main.rs index 34c3964..fa1cab8 100644 --- a/2018/src/main.rs +++ b/2018/src/main.rs @@ -26,8 +26,9 @@ mod day17; mod day18; mod day19; mod day20; +mod day21; -static NUM_DAYS: i32 = 20; +static NUM_DAYS: i32 = 21; fn day_switch(day: i32, reader: T) -> io::Result<(String, String)> { match day { @@ -51,6 +52,7 @@ fn day_switch(day: i32, reader: T) -> io::Result<(String, String)> { 18 => day18::main(reader), 19 => day19::main(reader), 20 => day20::main(reader), + 21 => day21::main(reader), _ => Err(Error::new(ErrorKind::Other, "Invalid day")) } } -- cgit v1.2.3-70-g09d2