day 7: part 2: rust

This commit is contained in:
Samuel Ortion 2024-11-29 19:55:24 +01:00
parent f3a948d4bf
commit 1a8565b67c
Signed by: sortion
GPG Key ID: 9B02406F8C4FB765
3 changed files with 110 additions and 0 deletions

7
2015/days/07/part2/Cargo.lock generated Normal file
View File

@ -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"

View File

@ -0,0 +1,6 @@
[package]
name = "part2"
version = "0.1.0"
edition = "2021"
[dependencies]

View File

@ -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<Variable, u16>, 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::<u16>();
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::<u16>();
let operand_b_u16_result = operand_b.parse::<u16>();
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<Variable, u16> = 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<Variable, u16> = 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(())
}