Skip to content

Commit

Permalink
day24
Browse files Browse the repository at this point in the history
  • Loading branch information
vslinko committed Dec 25, 2024
1 parent 87c1a9b commit d7b8e4f
Showing 1 changed file with 28 additions and 45 deletions.
73 changes: 28 additions & 45 deletions src/day24.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,19 @@ const Y: usize = b'y' as usize;
const Z: usize = b'z' as usize;
const CONTEXT_SIZE: usize = GATES_COUNT + X_Y_SIZE * 2;

#[derive(Clone, Eq, PartialEq)]
enum GateOperaion {
And,
Or,
Xor,
}
const OP_AND: u8 = b'A';
const OP_OR: u8 = b'O';
const OP_XOR: u8 = b'X';

#[derive(Clone)]
struct Gate {
a: usize,
op: GateOperaion,
op: u8,
b: usize,
}

impl Gate {
fn new(a: usize, op: GateOperaion, b: usize) -> Self {
fn new(a: usize, op: u8, b: usize) -> Self {
Gate { a, op, b }
}
}
Expand Down Expand Up @@ -80,21 +77,17 @@ unsafe fn inner1(input: &str) -> usize {
*input.get_unchecked(i + 2),
);

let op = match input.get_unchecked(i + 4) {
b'X' => {
i += 8;
GateOperaion::Xor
}
b'A' => {
let op = *input.get_unchecked(i + 4);

match op {
OP_AND | OP_XOR => {
i += 8;
GateOperaion::And
}
b'O' => {
OP_OR => {
i += 7;
GateOperaion::Or
}
_ => unreachable!(),
};
}

let b = key3(
*input.get_unchecked(i),
Expand Down Expand Up @@ -178,9 +171,10 @@ unsafe fn inner1(input: &str) -> usize {
let b = *outputs.get(&gate.b).unwrap_unchecked();

let output = match gate.op {
GateOperaion::And => a & b,
GateOperaion::Or => a | b,
GateOperaion::Xor => a ^ b,
OP_AND => a & b,
OP_OR => a | b,
OP_XOR => a ^ b,
_ => unreachable!(),
};

outputs.insert(wire, output);
Expand All @@ -200,7 +194,7 @@ unsafe fn swap(context: &mut FxHashMap<usize, Gate>, swaps: &mut Vec<usize>, a:
swaps.push(b);
}

fn gate_output(context: &FxHashMap<usize, Gate>, a: usize, op: GateOperaion, b: usize) -> usize {
fn gate_output(context: &FxHashMap<usize, Gate>, a: usize, op: u8, b: usize) -> usize {
context
.iter()
.find(|(_, gate)| {
Expand All @@ -227,21 +221,17 @@ unsafe fn inner2(input: &str) -> String {
*input.get_unchecked(i + 2),
);

let op = match input.get_unchecked(i + 4) {
b'X' => {
i += 8;
GateOperaion::Xor
}
b'A' => {
let op = *input.get_unchecked(i + 4);

match op {
OP_AND | OP_XOR => {
i += 8;
GateOperaion::And
}
b'O' => {
OP_OR => {
i += 7;
GateOperaion::Or
}
_ => unreachable!(),
};
}

let b = key3(
*input.get_unchecked(i),
Expand All @@ -261,15 +251,15 @@ unsafe fn inner2(input: &str) -> String {
});

let mut swaps = Vec::with_capacity(8);
let mut prev_output = gate_output(&context, key2(X, 0), GateOperaion::And, key2(Y, 0));
let mut prev_output = gate_output(&context, key2(X, 0), OP_AND, key2(Y, 0));

(1..Z_SIZE - 1).for_each(|i| {
let x = key2(X, i);
let y = key2(Y, i);
let z = key2(Z, i);

loop {
let xor_gate_output = gate_output(&context, x, GateOperaion::Xor, y);
let xor_gate_output = gate_output(&context, x, OP_XOR, y);
let z_gate = context.get(&z).unwrap_unchecked();
let z_gate_input_a = z_gate.a;
let z_gate_input_b = z_gate.b;
Expand All @@ -284,24 +274,17 @@ unsafe fn inner2(input: &str) -> String {
continue;
}

let z_gate_output =
gate_output(&context, xor_gate_output, GateOperaion::Xor, prev_output);
let z_gate_output = gate_output(&context, xor_gate_output, OP_XOR, prev_output);

if z_gate_output != z {
swap(&mut context, &mut swaps, z_gate_output, z);
continue;
}

let and_gate_output1 = gate_output(&context, x, GateOperaion::And, y);
let and_gate_output2 =
gate_output(&context, xor_gate_output, GateOperaion::And, prev_output);
let and_gate_output1 = gate_output(&context, x, OP_AND, y);
let and_gate_output2 = gate_output(&context, xor_gate_output, OP_AND, prev_output);

prev_output = gate_output(
&context,
and_gate_output1,
GateOperaion::Or,
and_gate_output2,
);
prev_output = gate_output(&context, and_gate_output1, OP_OR, and_gate_output2);

break;
}
Expand Down

0 comments on commit d7b8e4f

Please sign in to comment.