day 7: part 1: rust

This commit is contained in:
Samuel Ortion 2024-11-29 19:33:19 +01:00
parent 031471c8eb
commit f3a948d4bf
Signed by: sortion
GPG Key ID: 9B02406F8C4FB765
2 changed files with 98 additions and 0 deletions

View File

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

View File

@ -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<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 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(())
}