diff --git a/2015/days/07/part1/Cargo.toml b/2015/days/07/part1/Cargo.toml new file mode 100644 index 0000000..d85b608 --- /dev/null +++ b/2015/days/07/part1/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "part1" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/2015/days/07/part1/src/main.rs b/2015/days/07/part1/src/main.rs new file mode 100644 index 0000000..82f057c --- /dev/null +++ b/2015/days/07/part1/src/main.rs @@ -0,0 +1,92 @@ +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 target: 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, &target); + println!("{}", variables.get(&target).unwrap()); + Ok(()) +}