Skip to content

Commit cdee940

Browse files
2024: Improve day 24
1 parent ed7ac7e commit cdee940

File tree

1 file changed

+59
-6
lines changed

1 file changed

+59
-6
lines changed

2024/day24/src/main.rs

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::{HashMap, VecDeque};
1+
use std::collections::{HashMap, HashSet, VecDeque};
22
use std::fs::{self, File};
33
use std::io::{BufWriter, Write};
44

@@ -158,9 +158,60 @@ fn main() {
158158
println!("{}", total1);
159159

160160
// part 2
161-
let x = get_value(&wires, "x");
162-
let y = get_value(&wires, "y");
161+
// try to find broken nodes by checking common patterns (this is basically
162+
// what I've done visually)
163+
let mut edges: HashMap<&str, Vec<&str>> = HashMap::new();
164+
for g in &gates {
165+
edges.entry(g.a).or_default().push(g.out);
166+
edges.entry(g.b).or_default().push(g.out);
167+
}
168+
169+
let mut broken_nodes = HashSet::new();
170+
for g in &gates {
171+
// z nodes must be XOR (except for the last one, z45)
172+
if g.out.starts_with("z") && g.out != "z45" && g.logic != Logic::Xor {
173+
broken_nodes.insert(g.out);
174+
}
175+
// z nodes must not be inputs of other nodes
176+
if g.a.starts_with("z") {
177+
broken_nodes.insert(g.a);
178+
}
179+
if g.b.starts_with("z") {
180+
broken_nodes.insert(g.b);
181+
}
182+
183+
// inputs of XOR nodes (except for z nodes) must be x and y nodes
184+
if g.logic == Logic::Xor
185+
&& !g.out.starts_with("z")
186+
&& !((g.a.starts_with("x") && g.b.starts_with("y"))
187+
|| (g.a.starts_with("y") && g.b.starts_with("x")))
188+
{
189+
broken_nodes.insert(g.out);
190+
}
163191

192+
// XOR nodes (except z nodes) must always be input of exactly two
193+
// other nodes
194+
if g.logic == Logic::Xor && !g.out.starts_with("z") && edges[g.out].len() != 2 {
195+
broken_nodes.insert(g.out);
196+
}
197+
198+
// AND nodes must always be input of exactly one other node (except
199+
// the very first one wired to x00 and y00)
200+
if g.logic == Logic::And
201+
&& !g.out.starts_with("z")
202+
&& edges[g.out].len() != 1
203+
&& !((g.a == "x00" && g.b == "y00") || (g.a == "y00" && g.b == "x00"))
204+
{
205+
broken_nodes.insert(g.out);
206+
}
207+
}
208+
209+
// this should be the answer:
210+
let mut broken_nodes = broken_nodes.into_iter().collect::<Vec<_>>();
211+
broken_nodes.sort();
212+
println!("{}", broken_nodes.join(","));
213+
214+
// hard-coded answer for my puzzle input
164215
let renames = HashMap::from([
165216
// 1
166217
("kqh", "ddn"),
@@ -176,11 +227,13 @@ fn main() {
176227
("wrc", "z34"),
177228
]);
178229

230+
let x = get_value(&wires, "x");
231+
let y = get_value(&wires, "y");
179232
let total2 = run(&wires, &gates, &renames);
180233
if total2 == x + y {
181-
let mut broken_wires = renames.keys().copied().collect::<Vec<_>>();
182-
broken_wires.sort();
183-
println!("{}", broken_wires.join(","));
234+
let mut broken_nodes2 = renames.keys().copied().collect::<Vec<_>>();
235+
broken_nodes2.sort();
236+
assert_eq!(broken_nodes, broken_nodes2);
184237
} else {
185238
panic!("Unsolvable");
186239
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy