From d9b5a89702f737cd156a71c57c324a225e3f234b Mon Sep 17 00:00:00 2001 From: inga-lovinde <52715130+inga-lovinde@users.noreply.github.com> Date: Tue, 15 Dec 2020 11:56:06 +0100 Subject: [PATCH] Solution for day 14 part 2 --- day14-hard/Cargo.toml | 11 +++++ day14-hard/src/main.rs | 97 ++++++++++++++++++++++++++++++++++++++++++ day14/src/main.rs | 1 - 3 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 day14-hard/Cargo.toml create mode 100644 day14-hard/src/main.rs diff --git a/day14-hard/Cargo.toml b/day14-hard/Cargo.toml new file mode 100644 index 0000000..2a96f68 --- /dev/null +++ b/day14-hard/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "day14-hard" +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/day14-hard/src/main.rs b/day14-hard/src/main.rs new file mode 100644 index 0000000..334d6bf --- /dev/null +++ b/day14-hard/src/main.rs @@ -0,0 +1,97 @@ +use std::collections::HashMap; +use std::error::Error; +use std::io::{self, BufRead}; +use std::str::FromStr; + +#[macro_use] extern crate lazy_static; +use regex::Regex; + +#[derive(Clone, Copy, Debug)] +struct Mask { + pub bypass: u64, + pub floating: u64, + pub ones: u64, +} + +#[derive(Clone, Copy, Debug)] +enum Instruction { + SetMask(Mask), + SetValue{ address: u64, value: u128 }, +} + +impl FromStr for Instruction { + type Err = Box; + + fn from_str(s: &str) -> Result { + lazy_static! { + static ref MASK_RE: Regex = Regex::new(r"^mask\s*=\s*([01X]+)$").unwrap(); + static ref MEM_RE: Regex = Regex::new(r"^mem\[(\d+)\]\s*=\s*(\d+)$").unwrap(); + } + + match (MASK_RE.captures(s), MEM_RE.captures(s)) { + (Some(mask_captures), None) => Ok(Self::SetMask(Mask { + bypass: u64::from_str_radix(&mask_captures[1].replace("1", "X").replace("0", "1").replace("X", "0"), 2)?, + floating: u64::from_str_radix(&mask_captures[1].replace("1", "0").replace("X", "1"), 2)?, + ones: u64::from_str_radix(&mask_captures[1].replace("X", "0"), 2)?, + })), + (None, Some(mem_re)) => Ok(Self::SetValue { + address: mem_re[1].parse()?, + value: mem_re[2].parse()?, + }), + _ => Err(Box::from("Wrong string format")), + } + } +} + +struct ProgramState { + mask: Mask, + memory: HashMap, +} + +impl ProgramState { + pub fn new() -> ProgramState { + ProgramState { + mask: Mask { + bypass: !0, + floating: 0, + ones: 0, + }, + memory: HashMap::new(), + } + } + + pub fn apply_instruction(&mut self, instruction: Instruction) -> () { + match instruction { + Instruction::SetMask(mask) => self.mask = mask, + Instruction::SetValue{ address, value } => { + let address_min = (address & self.mask.bypass) | self.mask.ones; + let address_max = address_min | self.mask.floating; + for i in address_min..=address_max { // insanely slow, could be optimized, but I'm lazy :( + if (i & address_min) == address_min && (i & address_max) == i { + self.memory.insert(i, value); + println!("Inserting {} into {}", value, i); + } + } + } + } + } + + pub fn get_sum(&self) -> u128 { + self.memory.values().sum() + } +} + +fn main() { + let stdin = io::stdin(); + let instructions: Vec<_> = stdin.lock().lines().into_iter() + .map(|line| line.unwrap().parse::().unwrap()) + .collect(); + + let mut program_state = ProgramState::new(); + for instruction in instructions { + program_state.apply_instruction(instruction); + println!("Processed instruction"); + } + + println!("{}", program_state.get_sum()); +} diff --git a/day14/src/main.rs b/day14/src/main.rs index e93f847..66e8da7 100644 --- a/day14/src/main.rs +++ b/day14/src/main.rs @@ -1,4 +1,3 @@ -use std::collections::HashSet; use std::io::{self, BufRead}; use std::error::Error; use std::str::FromStr;