Add day24 part1
This commit is contained in:
parent
95b654234f
commit
6efeba3111
7
day24/Cargo.lock
generated
Normal file
7
day24/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day24"
|
||||||
|
version = "0.1.0"
|
||||||
6
day24/Cargo.toml
Normal file
6
day24/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "day24"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
105
day24/src/main.rs
Normal file
105
day24/src/main.rs
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
use std::{cmp::Reverse, collections::HashMap};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
enum Gate {
|
||||||
|
InputGate(bool),
|
||||||
|
CalcGate(CalcGate),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
|
enum Operation {
|
||||||
|
And,
|
||||||
|
Or,
|
||||||
|
Xor,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for Operation {
|
||||||
|
fn from(value: &str) -> Self {
|
||||||
|
match value {
|
||||||
|
"AND" => Self::And,
|
||||||
|
"OR" => Self::Or,
|
||||||
|
"XOR" => Self::Xor,
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
struct CalcGate {
|
||||||
|
operation: Operation,
|
||||||
|
lhs: String,
|
||||||
|
rhs: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(input: &str) -> HashMap<String, Gate> {
|
||||||
|
let mut res = HashMap::new();
|
||||||
|
let (inputs, calcs) = input.split_once("\n\n").unwrap();
|
||||||
|
res.extend(inputs.lines().map(|l| {
|
||||||
|
let (name, val) = l.split_once(": ").unwrap();
|
||||||
|
(name.to_string(), Gate::InputGate(val == "1"))
|
||||||
|
}));
|
||||||
|
res.extend(calcs.lines().map(|l| {
|
||||||
|
let mut iter = l.split(' ');
|
||||||
|
let lhs = iter.next().unwrap();
|
||||||
|
let op = iter.next().unwrap();
|
||||||
|
let rhs = iter.next().unwrap();
|
||||||
|
let name = iter.nth(1).unwrap();
|
||||||
|
(
|
||||||
|
name.to_string(),
|
||||||
|
Gate::CalcGate(CalcGate {
|
||||||
|
operation: Operation::from(op),
|
||||||
|
lhs: lhs.to_string(),
|
||||||
|
rhs: rhs.to_string(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}));
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_gate_value(
|
||||||
|
gate: &str,
|
||||||
|
gates: &HashMap<String, Gate>,
|
||||||
|
cache: &mut HashMap<String, bool>,
|
||||||
|
) -> bool {
|
||||||
|
if let Some(v) = cache.get(gate) {
|
||||||
|
return *v;
|
||||||
|
}
|
||||||
|
let res = match gates.get(gate).unwrap() {
|
||||||
|
Gate::InputGate(val) => *val,
|
||||||
|
Gate::CalcGate(calc_gate) => match calc_gate.operation {
|
||||||
|
Operation::And => {
|
||||||
|
get_gate_value(&calc_gate.lhs, gates, cache)
|
||||||
|
& get_gate_value(&calc_gate.rhs, gates, cache)
|
||||||
|
}
|
||||||
|
Operation::Or => {
|
||||||
|
get_gate_value(&calc_gate.lhs, gates, cache)
|
||||||
|
| get_gate_value(&calc_gate.rhs, gates, cache)
|
||||||
|
}
|
||||||
|
Operation::Xor => {
|
||||||
|
get_gate_value(&calc_gate.lhs, gates, cache)
|
||||||
|
^ get_gate_value(&calc_gate.rhs, gates, cache)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
cache.insert(gate.to_string(), res);
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(gates: &HashMap<String, Gate>) -> usize {
|
||||||
|
let mut output_bits: Vec<_> = gates.keys().filter(|g| g.starts_with("z")).collect();
|
||||||
|
let mut cache = HashMap::new();
|
||||||
|
output_bits.sort_unstable_by_key(|v| Reverse(v.to_string()));
|
||||||
|
let mut res: usize = 0;
|
||||||
|
for bit in output_bits {
|
||||||
|
res <<= 1;
|
||||||
|
if get_gate_value(bit, gates, &mut cache) {
|
||||||
|
res += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input = parse(include_str!("../input.txt"));
|
||||||
|
println!("{}", part1(&input));
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user