Skip to content

Commit 834c4fb

Browse files
committed
Solve the second part of the day 24 puzzle
1 parent 95ad04d commit 834c4fb

File tree

1 file changed

+84
-3
lines changed

1 file changed

+84
-3
lines changed

day24/src/main.rs

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::{HashMap, HashSet, VecDeque};
1+
use std::collections::{HashMap, VecDeque};
22
use std::env;
33
use std::fs::File;
44
use std::io::{BufRead, BufReader};
@@ -9,11 +9,92 @@ type Circuit = HashMap<(String, usize), (String, String, String)>;
99
fn main() {
1010
let args = env::args().collect::<Vec<String>>();
1111
if let Ok((state, circuit)) = get_init_state_and_circuit(&args[1]) {
12-
println!("{:?}", solve(state, circuit))
12+
println!("{:?}", solve1(state, &circuit));
13+
println!("{:?}", solve2(circuit));
1314
}
1415
}
1516

16-
fn solve(mut state: State, circuit: Circuit) -> i64 {
17+
fn solve2(circuit: Circuit) -> String {
18+
let mut swapped_wires = circuit
19+
.iter()
20+
.filter_map(
21+
|((gate_type, _), (in1, in2, out))| match gate_type.as_str() {
22+
"AND" => is_invalid_and(in1, in2, out, &circuit),
23+
"OR" => is_invalid_or(out, &circuit),
24+
"XOR" => is_invalid_xor(in1, in2, out, &circuit),
25+
_ => panic!("How?"),
26+
},
27+
)
28+
.collect::<Vec<String>>();
29+
swapped_wires.sort();
30+
swapped_wires.join(",")
31+
}
32+
33+
fn is_invalid_xor(in1: &String, in2: &String, out: &String, circuit: &Circuit) -> Option<String> {
34+
if in1.starts_with("x") && in2.starts_with("y") || in1.starts_with("y") && in2.starts_with("x")
35+
{
36+
let bit_position = &in1[1..];
37+
let z = format!("z{}", bit_position);
38+
let flag1 = bit_position == "00" && &z == out;
39+
let flag2 =
40+
find_ins(&z, String::from("XOR"), &circuit).filter(|e| &e.0 == out || &e.1 == out);
41+
let flag3 = find_gate_with_in(String::from("AND"), out, &circuit);
42+
if flag1 || flag2.is_some() || flag3.is_some() {
43+
None
44+
} else {
45+
Some(out.to_string())
46+
}
47+
} else if !out.starts_with("z") {
48+
Some(out.to_string())
49+
} else {
50+
None
51+
}
52+
}
53+
54+
fn is_invalid_or(out: &String, circuit: &Circuit) -> Option<String> {
55+
let max_z = circuit
56+
.values()
57+
.filter(|e| e.2.starts_with("z"))
58+
.max_by_key(|e| &e.2)
59+
.unwrap();
60+
let flag1 = *out == max_z.2;
61+
let flag2 = find_gate_with_in(String::from("XOR"), out, circuit).is_some()
62+
&& find_gate_with_in(String::from("AND"), out, circuit).is_some();
63+
if flag1 || flag2 {
64+
None
65+
} else {
66+
Some(out.to_string())
67+
}
68+
}
69+
fn is_invalid_and(in1: &String, in2: &String, out: &String, circuit: &Circuit) -> Option<String> {
70+
let flag1 = in1 == "x00" && in2 == "y00" || in1 == "y00" && in2 == "x00";
71+
let flag2 = find_gate_with_in(String::from("OR"), out, circuit).is_some();
72+
if flag1 || flag2 {
73+
None
74+
} else {
75+
Some(out.to_string())
76+
}
77+
}
78+
79+
fn find_gate_with_in(
80+
gate_type: String,
81+
input: &String,
82+
circuit: &Circuit,
83+
) -> Option<(String, String, String)> {
84+
circuit
85+
.iter()
86+
.find(|(k, v)| k.0 == *gate_type && (v.0 == *input || v.1 == *input))
87+
.map(|(_, v)| v.clone())
88+
}
89+
90+
fn find_ins(z: &String, gate_type: String, circuit: &Circuit) -> Option<(String, String)> {
91+
circuit
92+
.iter()
93+
.find(|(k, v)| k.0 == *gate_type && (v.2 == *z))
94+
.map(|e| (e.1 .0.clone(), e.1 .1.clone()))
95+
}
96+
97+
fn solve1(mut state: State, circuit: &Circuit) -> i64 {
1798
let mut gates: VecDeque<&(String, usize)> =
1899
VecDeque::<&(String, usize)>::from(circuit.keys().collect::<Vec<&(String, usize)>>());
19100
while !gates.is_empty() {

0 commit comments

Comments
 (0)