Rust/2024/24: add solution
This commit is contained in:
parent
656311ff36
commit
b273e3470f
8 changed files with 218 additions and 3 deletions
File diff suppressed because one or more lines are too long
153
Rust/2024/24.rs
Normal file
153
Rust/2024/24.rs
Normal file
|
@ -0,0 +1,153 @@
|
|||
#![feature(test)]
|
||||
#![expect(unstable_name_collisions)]
|
||||
|
||||
use itertools::Itertools;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Input {
|
||||
values: FxHashMap<String, bool>,
|
||||
gates: FxHashMap<String, (Gate, String, String)>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum Gate {
|
||||
And,
|
||||
Or,
|
||||
Xor,
|
||||
}
|
||||
|
||||
fn setup(input: &str) -> Input {
|
||||
let mut lines = input.lines();
|
||||
let values = lines
|
||||
.by_ref()
|
||||
.take_while(|l| !l.trim().is_empty())
|
||||
.map(|l| {
|
||||
let mut s = l.split(": ");
|
||||
let name = s.next().unwrap().into();
|
||||
let value = s.next().unwrap().trim() == "1";
|
||||
(name, value)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let gates = lines
|
||||
.map(|l| {
|
||||
let mut s = l.split_whitespace();
|
||||
let a = s.next().unwrap().into();
|
||||
let gate = match s.next().unwrap() {
|
||||
"AND" => Gate::And,
|
||||
"OR" => Gate::Or,
|
||||
"XOR" => Gate::Xor,
|
||||
_ => panic!(),
|
||||
};
|
||||
let b = s.next().unwrap().into();
|
||||
s.next();
|
||||
let c = s.next().unwrap().into();
|
||||
(c, (gate, a, b))
|
||||
})
|
||||
.collect();
|
||||
|
||||
Input { values, gates }
|
||||
}
|
||||
|
||||
fn part1(input: &Input) -> usize {
|
||||
let mut forward = FxHashMap::<_, Vec<_>>::default();
|
||||
let mut unknown = input
|
||||
.gates
|
||||
.iter()
|
||||
.map(|(c, (_, a, b))| {
|
||||
forward.entry(a).or_default().push(c);
|
||||
forward.entry(b).or_default().push(c);
|
||||
let dependencies = [a, b]
|
||||
.into_iter()
|
||||
.filter(|&x| !input.values.contains_key(x))
|
||||
.collect::<FxHashSet<_>>();
|
||||
(c, dependencies)
|
||||
})
|
||||
.filter(|(_, v)| !v.is_empty())
|
||||
.collect::<FxHashMap<_, _>>();
|
||||
let mut values = input
|
||||
.values
|
||||
.iter()
|
||||
.map(|(p, &v)| (p, v))
|
||||
.collect::<FxHashMap<_, _>>();
|
||||
let mut stack = input
|
||||
.gates
|
||||
.keys()
|
||||
.filter(|&p| !unknown.contains_key(p))
|
||||
.collect::<Vec<_>>();
|
||||
while let Some(p) = stack.pop() {
|
||||
let (gate, ref a, ref b) = input.gates[p];
|
||||
let a = values[a];
|
||||
let b = values[b];
|
||||
let c = match gate {
|
||||
Gate::And => a & b,
|
||||
Gate::Or => a | b,
|
||||
Gate::Xor => a ^ b,
|
||||
};
|
||||
values.insert(p, c);
|
||||
|
||||
for &q in forward.get(p).into_iter().flatten() {
|
||||
if unknown.contains_key(q) {
|
||||
unknown.get_mut(q).unwrap().remove(p);
|
||||
if unknown[q].is_empty() {
|
||||
unknown.remove(q);
|
||||
stack.push(q);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
values
|
||||
.keys()
|
||||
.filter(|k| k.starts_with('z'))
|
||||
.sorted_unstable()
|
||||
.rev()
|
||||
.fold(0, |acc, k| acc << 1 | (values[k] as usize))
|
||||
}
|
||||
|
||||
fn part2(input: &Input) -> String {
|
||||
let last_z = input
|
||||
.gates
|
||||
.keys()
|
||||
.filter(|k| k.starts_with('z'))
|
||||
.max()
|
||||
.unwrap();
|
||||
let mut forward = FxHashMap::<_, Vec<_>>::default();
|
||||
for (c, (_, a, b)) in &input.gates {
|
||||
forward.entry(a).or_default().push(c);
|
||||
forward.entry(b).or_default().push(c);
|
||||
}
|
||||
input
|
||||
.gates
|
||||
.keys()
|
||||
.filter(|&g| {
|
||||
let (gate, ref a, ref b) = input.gates[g];
|
||||
gate != Gate::Xor && g.starts_with('z') && g != last_z
|
||||
|| gate == Gate::Xor
|
||||
&& forward
|
||||
.get(g)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.any(|&x| input.gates[x].0 == Gate::Or)
|
||||
|| gate == Gate::And
|
||||
&& a != "x00"
|
||||
&& b != "x00"
|
||||
&& forward
|
||||
.get(g)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.any(|&x| input.gates[x].0 != Gate::Or)
|
||||
|| gate == Gate::Xor
|
||||
&& !g.starts_with('z')
|
||||
&& [a, b]
|
||||
.into_iter()
|
||||
.any(|x| input.gates.get(x).is_some_and(|x| x.0 == Gate::Xor))
|
||||
})
|
||||
.sorted_unstable()
|
||||
.map(|s| s.as_str())
|
||||
.intersperse(",")
|
||||
.collect()
|
||||
}
|
||||
|
||||
aoc::main!(2024, 24, ex: 1[a], 2[a]);
|
|
@ -22,6 +22,6 @@ aoc::year! {
|
|||
"21.rs",
|
||||
"22.rs",
|
||||
"23.rs",
|
||||
// "24.rs",
|
||||
"24.rs",
|
||||
"25.rs",
|
||||
}
|
||||
|
|
|
@ -430,5 +430,8 @@ path = "2024/22.rs"
|
|||
name = "2024_23"
|
||||
path = "2024/23.rs"
|
||||
[[bin]]
|
||||
name = "2024_24"
|
||||
path = "2024/24.rs"
|
||||
[[bin]]
|
||||
name = "2024_25"
|
||||
path = "2024/25.rs"
|
||||
|
|
10
examples/2024/24/1
Normal file
10
examples/2024/24/1
Normal file
|
@ -0,0 +1,10 @@
|
|||
x00: 1
|
||||
x01: 1
|
||||
x02: 1
|
||||
y00: 0
|
||||
y01: 1
|
||||
y02: 0
|
||||
|
||||
x00 AND y00 -> z00
|
||||
x01 XOR y01 -> z01
|
||||
x02 OR y02 -> z02
|
1
examples/2024/24/1.1
Normal file
1
examples/2024/24/1.1
Normal file
|
@ -0,0 +1 @@
|
|||
4
|
47
examples/2024/24/2
Normal file
47
examples/2024/24/2
Normal file
|
@ -0,0 +1,47 @@
|
|||
x00: 1
|
||||
x01: 0
|
||||
x02: 1
|
||||
x03: 1
|
||||
x04: 0
|
||||
y00: 1
|
||||
y01: 1
|
||||
y02: 1
|
||||
y03: 1
|
||||
y04: 1
|
||||
|
||||
ntg XOR fgs -> mjb
|
||||
y02 OR x01 -> tnw
|
||||
kwq OR kpj -> z05
|
||||
x00 OR x03 -> fst
|
||||
tgd XOR rvg -> z01
|
||||
vdt OR tnw -> bfw
|
||||
bfw AND frj -> z10
|
||||
ffh OR nrd -> bqk
|
||||
y00 AND y03 -> djm
|
||||
y03 OR y00 -> psh
|
||||
bqk OR frj -> z08
|
||||
tnw OR fst -> frj
|
||||
gnj AND tgd -> z11
|
||||
bfw XOR mjb -> z00
|
||||
x03 OR x00 -> vdt
|
||||
gnj AND wpb -> z02
|
||||
x04 AND y00 -> kjc
|
||||
djm OR pbm -> qhw
|
||||
nrd AND vdt -> hwm
|
||||
kjc AND fst -> rvg
|
||||
y04 OR y02 -> fgs
|
||||
y01 AND x02 -> pbm
|
||||
ntg OR kjc -> kwq
|
||||
psh XOR fgs -> tgd
|
||||
qhw XOR tgd -> z09
|
||||
pbm OR djm -> kpj
|
||||
x03 XOR y03 -> ffh
|
||||
x00 XOR y04 -> ntg
|
||||
bfw OR bqk -> z06
|
||||
nrd XOR fgs -> wpb
|
||||
frj XOR qhw -> z04
|
||||
bqk OR frj -> z07
|
||||
y03 OR x01 -> nrd
|
||||
hwm AND bqk -> z03
|
||||
tgd XOR rvg -> z12
|
||||
tnw OR pbm -> gnj
|
1
examples/2024/24/2.1
Normal file
1
examples/2024/24/2.1
Normal file
|
@ -0,0 +1 @@
|
|||
2024
|
Loading…
Add table
Add a link
Reference in a new issue