From 351b0eb897d7ede2273e3f48097231de3396f4d2 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Sat, 23 Dec 2017 10:42:47 +0200 Subject: Day 23: Rewrite this assembly as a decent program... --- inputs/day_23.txt | 32 +++++++++++ src/bin/day_23.rs | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 inputs/day_23.txt diff --git a/inputs/day_23.txt b/inputs/day_23.txt new file mode 100644 index 0000000..9d29443 --- /dev/null +++ b/inputs/day_23.txt @@ -0,0 +1,32 @@ +set b 99 +set c b +jnz a 2 +jnz 1 5 +mul b 100 +sub b -100000 +set c b +sub c -17000 +set f 1 +set d 2 +set e 2 +set g d +mul g e +sub g b +jnz g 2 +set f 0 +sub e -1 +set g e +sub g b +jnz g -8 +sub d -1 +set g d +sub g b +jnz g -13 +jnz f 2 +sub h -1 +set g b +sub g c +jnz g 2 +jnz 1 3 +sub b -17 +jnz 1 -23 diff --git a/src/bin/day_23.rs b/src/bin/day_23.rs index 1fc3eca..d199af0 100644 --- a/src/bin/day_23.rs +++ b/src/bin/day_23.rs @@ -1,6 +1,168 @@ extern crate advent_of_code_2017; use advent_of_code_2017::*; +use std::str::FromStr; + fn main() { let args = AdventArgs::init(); + + if args.part == 1 { + let instructions: Vec = args.input.iter() + .map(|line| line.parse().unwrap()) + .collect(); + + let mut program = Program::new(instructions.clone(), args.part == 1); + let mul_called = program.run(); + println!("Mult called {} times", mul_called); + } else { + println!("Result is {}", run_as_rust()); + } + +} + +fn to_register(c: char) -> usize { + (c as u32 - 'a' as u32) as usize +} + +struct Program { + instructions: Vec, + registers: [i64; 8], + pc: i64 +} + +impl Program { + fn new(instructions: Vec, part1: bool) -> Program { + let mut reg = [0; 8]; + if part1 == false { + reg[0] = 1; + } + Program { + instructions: instructions, + registers: reg, + pc: 0 + } + } + fn run(&mut self) -> u32 { + use Instruction::*; + + let mut mul_called = 0; + + while self.pc >= 0 && (self.pc as usize) < self.instructions.len() { + let ins = self.instructions[self.pc as usize].clone(); + + match ins { + Set(x, y) => { + let y_val = self.get(y); + self.set(x, y_val); + }, + Sub(x, y) => { + let x_val = self.get(x); + let y_val = self.get(y); + self.set(x, x_val - y_val); + }, + Mul(x, y) => { + let x_val = self.get(x); + let y_val = self.get(y); + self.set(x, x_val * y_val); + mul_called += 1; + }, + Jnz(x, y) => { + if self.get(x) != 0 { + self.pc = self.pc + self.get(y) - 1; + } + }, + } + self.pc += 1; + } + + mul_called + } + + fn get(&self, register: Data) -> i64 { + use Data::*; + match register { + Register(c) => self.registers[c], + Literal(i) => i + } + } + + fn set(&mut self, register: Data, value: i64) { + use Data::*; + match register { + Register(c) => { + self.registers[c] = value; + }, + _ => {} + } + } +} + +#[derive(Debug, Clone)] +enum Instruction { + Set(Data, Data), + Sub(Data, Data), + Mul(Data, Data), + Jnz(Data, Data) +} + +impl FromStr for Instruction { + type Err = String; + + fn from_str(s: &str) -> Result { + use Instruction::*; + + let mut str_iter = s.split_whitespace(); + let ins = str_iter.next(); + let x = str_iter.next().map(|x| x.parse::()); + let y = str_iter.next().map(|x| x.parse::()); + + match (ins, x, y) { + (Some("set"), Some(Ok(x)), Some(Ok(y))) => Ok(Set(x, y)), + (Some("sub"), Some(Ok(x)), Some(Ok(y))) => Ok(Sub(x, y)), + (Some("mul"), Some(Ok(x)), Some(Ok(y))) => Ok(Mul(x, y)), + (Some("jnz"), Some(Ok(x)), Some(Ok(y))) => Ok(Jnz(x, y)), + (_, _, _) => Err(format!("Unknown instruction {}", s)) + } + } +} + +#[derive(Debug, Clone, Copy)] +enum Data { + Literal(i64), + Register(usize) +} + +impl FromStr for Data { + type Err = String; + + fn from_str(s: &str) -> Result { + use Data::*; + + match (s.parse(), s.chars().next()) { + (Ok(num), _) => Ok(Literal(num)), + (Err(_), Some(c)) => Ok(Register(to_register(c))), + (_, _) => Err(format!("Invalid data {}", s)) + } + } +} + + +fn run_as_rust() -> i64 { + let mut h: i64 = 0; + let mut b: i64 = 99 * 100 + 100000; + let c: i64 = b + 17000; + + while b <= c { + let f = (2..b).any(|d| { + b % d == 0 + }); + + if f { + h += 1; + } + + b += 17; + } + + h } -- cgit v1.2.3