From c99848b907d2d63577ffdc81fc11a77e4d328a92 Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Tue, 19 Apr 2022 20:24:37 +0200 Subject: Refile for merging repos --- 2017/src/bin/day_23.rs | 168 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 2017/src/bin/day_23.rs (limited to '2017/src/bin/day_23.rs') diff --git a/2017/src/bin/day_23.rs b/2017/src/bin/day_23.rs new file mode 100644 index 0000000..d199af0 --- /dev/null +++ b/2017/src/bin/day_23.rs @@ -0,0 +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