From 1a8565b67c8558f175d937c23a00cdfb23e6185a Mon Sep 17 00:00:00 2001 From: Samuel Ortion Date: Fri, 29 Nov 2024 19:55:24 +0100 Subject: [PATCH] day 7: part 2: rust --- 2015/days/07/part2/Cargo.lock | 7 +++ 2015/days/07/part2/Cargo.toml | 6 +++ 2015/days/07/part2/src/main.rs | 97 ++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 2015/days/07/part2/Cargo.lock create mode 100644 2015/days/07/part2/Cargo.toml create mode 100644 2015/days/07/part2/src/main.rs diff --git a/2015/days/07/part2/Cargo.lock b/2015/days/07/part2/Cargo.lock new file mode 100644 index 0000000..d292d19 --- /dev/null +++ b/2015/days/07/part2/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "part2" +version = "0.1.0" diff --git a/2015/days/07/part2/Cargo.toml b/2015/days/07/part2/Cargo.toml new file mode 100644 index 0000000..2001cb3 --- /dev/null +++ b/2015/days/07/part2/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "part2" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/2015/days/07/part2/src/main.rs b/2015/days/07/part2/src/main.rs new file mode 100644 index 0000000..a18a266 --- /dev/null +++ b/2015/days/07/part2/src/main.rs @@ -0,0 +1,97 @@ +use core::panic; +use std::io; +use std::collections::BTreeMap; + +type Formula = String; +type Variable = String; + +fn emulate(circuit: &Vec<(Formula, Variable)>, variables: &mut BTreeMap, target: &Variable) { + while !variables.contains_key(target) { + let mut update = true; + for command in circuit { + let variable = &command.1; + let formula = &command.0; + if variables.contains_key(variable) { + continue; + } + let number = formula.parse::(); + if number.is_ok() { + variables.insert(variable.clone(), number.unwrap()); + update = true; + } else if formula.starts_with("NOT") { + let mut parts = formula.split(" "); + parts.next(); + let negated = parts.next().unwrap().to_string(); + if variables.contains_key(&negated) { + let value = !(*variables.get(&negated).unwrap()); + variables.insert(variable.clone(), value); + update = true; + } + } else if !formula.contains(" "){ + if variables.contains_key(formula) { + let value = *variables.get(formula).unwrap(); + variables.insert(variable.clone(),value); + update = true; + } + } else { + let mut parts = formula.split(" "); + let operand_a = parts.next().unwrap(); + let operator = parts.next().unwrap(); + let operand_b = parts.next().unwrap(); + let operand_a_u16_result = operand_a.parse::(); + let operand_b_u16_result = operand_b.parse::(); + if (!operand_a_u16_result.is_ok() && !variables.contains_key(operand_a)) + || (!operand_b_u16_result.is_ok() && !variables.contains_key(operand_b)) { + continue; + } + let operand_a_u16: u16; + let operand_b_u16: u16; + if operand_a_u16_result.is_ok() { + operand_a_u16 = operand_a_u16_result.unwrap(); + } else { + operand_a_u16 = *variables.get(operand_a).unwrap(); + } + if operand_b_u16_result.is_ok() { + operand_b_u16 = operand_b_u16_result.unwrap(); + } else { + operand_b_u16 = *variables.get(operand_b).unwrap(); + } + let value = match operator { + "AND" => operand_a_u16 & operand_b_u16, + "OR" => operand_a_u16 | operand_b_u16, + "LSHIFT" => operand_a_u16 << operand_b_u16, + "RSHIFT" => operand_a_u16 >> operand_b_u16, + &_ => 0, + }; + variables.insert(variable.clone(), value); + update = true; + } + + } + + if !update { + panic!("I cannot progress in the emulation, target cannot be reached"); + } + } +} + +fn main() -> io::Result<()> { + let mut variables: BTreeMap = BTreeMap::new(); + let wire_a: Variable = "a".to_string(); + let mut circuit: Vec<(Formula, Variable)> = Vec::new(); + for line in io::stdin().lines() { + let line = line.unwrap(); + let mut parts = line.split(" -> "); + let formula: Formula = parts.next().unwrap().to_string(); + let variable: Variable = parts.next().unwrap().to_string(); + circuit.push((formula, variable)); + } + emulate(&circuit, &mut variables, &wire_a); + let signal_b = variables.get(&wire_a).unwrap(); + let wire_b = "b".to_string(); + let mut new_variables: BTreeMap = BTreeMap::new(); + new_variables.insert(wire_b.clone(), *signal_b); + emulate(&circuit, &mut new_variables, &wire_a); + println!("{}", new_variables.get(&wire_a).unwrap()); + Ok(()) +}