From aa33f429359d6b07f072d092dbdc1568de0adad1 Mon Sep 17 00:00:00 2001 From: inga-lovinde <52715130+inga-lovinde@users.noreply.github.com> Date: Sun, 13 Dec 2020 02:20:44 +0100 Subject: [PATCH] Solution for day 8 --- day08/Cargo.toml | 11 +++++ day08/src/main.rs | 120 ++++++++++++++++++++++++++++++++++++++++++++++ day09/src/main.rs | 1 - 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 day08/Cargo.toml create mode 100644 day08/src/main.rs diff --git a/day08/Cargo.toml b/day08/Cargo.toml new file mode 100644 index 0000000..4607d27 --- /dev/null +++ b/day08/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "day08" +version = "0.1.0" +authors = ["inga-lovinde <52715130+inga-lovinde@users.noreply.github.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +lazy_static = "1.4.0" +regex = "1" diff --git a/day08/src/main.rs b/day08/src/main.rs new file mode 100644 index 0000000..d5dce67 --- /dev/null +++ b/day08/src/main.rs @@ -0,0 +1,120 @@ +use std::collections::HashSet; +use std::io::{self, BufRead}; +use std::error::Error; +use std::str::FromStr; + +#[macro_use] extern crate lazy_static; +use regex::Regex; + +#[derive(Clone, Copy)] +enum Instruction { + Accumulate(i64), + Jump(i64), + NoOp(i64), +} + +impl FromStr for Instruction { + type Err = Box; + + fn from_str(s: &str) -> Result { + lazy_static! { + static ref LINE_RE: Regex = Regex::new(r"^(\w+)\s+([+-]?\d+)$").unwrap(); + } + + match LINE_RE.captures(s) { + Some(captures) => { + match captures[1].as_ref() { + "acc" => Ok(Self::Accumulate(captures[2].parse()?)), + "jmp" => Ok(Self::Jump(captures[2].parse()?)), + "nop" => Ok(Self::NoOp(captures[2].parse()?)), + _ => Err(Box::from("wrong command")), + } + }, + _ => Err(Box::from("wrong string format")) + } + } +} + +enum ProgramResult { + Terminated(i64), + Looped(i64), +} + +struct Program<'a> { + instructions: &'a[Instruction], + override_index: i64, +} + +impl<'a> Program<'a> { + pub fn new(instructions: &'a [Instruction], override_index: i64) -> Self { + Program { + instructions, + override_index, + } + } + + fn get_instruction(&self, index: i64) -> Option { + if index < 0 || (index as usize) >= self.instructions.len() { + return None; + } + + if index != self.override_index { + return Some(self.instructions[index as usize]); + } + + match self.instructions[index as usize] { + Instruction::Accumulate(value) => Some(Instruction::Accumulate(value)), + Instruction::Jump(ignore) => Some(Instruction::NoOp(ignore)), + Instruction::NoOp(offset) => Some(Instruction::Jump(offset)), + } + } + + pub fn run(&self) -> ProgramResult { + let mut current_instruction_index = 0; + let mut visited_instructions = HashSet::new(); + let mut accumulator = 0; + loop { + if visited_instructions.contains(¤t_instruction_index) { + return ProgramResult::Looped(accumulator); + } + + visited_instructions.insert(current_instruction_index); + + match self.get_instruction(current_instruction_index) { + Some(Instruction::Accumulate(value)) => { + accumulator += value; + }, + Some(Instruction::Jump(offset)) => { + current_instruction_index += offset-1; + } + Some(Instruction::NoOp(_)) => {}, + None => { + return ProgramResult::Terminated(accumulator); + } + } + + current_instruction_index += 1; + } + } +} + +fn main() { + let stdin = io::stdin(); + let instructions: Vec<_> = stdin.lock().lines().into_iter() + .map(|line| line.unwrap().parse::().unwrap()) + .collect(); + + let program = Program::new(&instructions, -1); + match program.run() { + ProgramResult::Looped(accumulator) => println!("Original program looped: {}", accumulator), + ProgramResult::Terminated(accumulator) => println!("Original program terminated: {}", accumulator), + } + + for i in 0..instructions.len() { + let program = Program::new(&instructions, i as i64); + match program.run() { + ProgramResult::Looped(_) => {}, + ProgramResult::Terminated(accumulator) => println!("Program #{} terminated: {}", i, accumulator), + } + } +} diff --git a/day09/src/main.rs b/day09/src/main.rs index 3367ded..e1a17aa 100644 --- a/day09/src/main.rs +++ b/day09/src/main.rs @@ -1,4 +1,3 @@ -use std::collections::HashMap; use std::io::{self, BufRead}; const BLOCK_SIZE: usize = 25;