day 7: part 2: rust
This commit is contained in:
parent
f3a948d4bf
commit
1a8565b67c
|
@ -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"
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "part2"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
|
@ -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(())
|
||||
}
|
Loading…
Reference in New Issue