Solve 2024 day 24
This commit is contained in:
parent
8cc199105c
commit
2ee16eb1ba
143
2024/d24.py
Normal file
143
2024/d24.py
Normal file
@ -0,0 +1,143 @@
|
||||
from lib import get_data
|
||||
from lib import ints
|
||||
|
||||
LHS, OP, RHS, _, OUT = 0, 1, 2, 3, 4
|
||||
|
||||
|
||||
def run(states, gates):
|
||||
change = True
|
||||
while change:
|
||||
change = False
|
||||
for gate in gates:
|
||||
i1, op, i2, _, out = gate
|
||||
if i1 in states and i2 in states and out not in states:
|
||||
change = True
|
||||
outv = None
|
||||
match op:
|
||||
case "OR":
|
||||
outv = states[i1] | states[i2]
|
||||
case "XOR":
|
||||
outv = states[i1] ^ states[i2]
|
||||
case "AND":
|
||||
outv = states[i1] & states[i2]
|
||||
assert outv is not None
|
||||
states[out] = outv
|
||||
|
||||
i, t = 0, 0
|
||||
while True:
|
||||
si = f"z{i:02}"
|
||||
if not si in states:
|
||||
break
|
||||
if states[si]:
|
||||
t += 2**i
|
||||
i += 1
|
||||
return t
|
||||
|
||||
|
||||
data = get_data(__file__)
|
||||
|
||||
s1, s2 = data.split("\n\n")
|
||||
states = {}
|
||||
for line in s1.splitlines():
|
||||
gate, value = line.split(": ")
|
||||
states[gate] = int(value)
|
||||
|
||||
gates = []
|
||||
out_to_index = {}
|
||||
xors = {}
|
||||
zz = []
|
||||
for i, line in enumerate(s2.splitlines()):
|
||||
o1, op, o2, _, out = line.split()
|
||||
o1, o2 = sorted([o1, o2])
|
||||
gate = [o1, op, o2, "->", out]
|
||||
gates.append(gate)
|
||||
out_to_index[out] = i
|
||||
if out.startswith("z"):
|
||||
zz.append(out)
|
||||
if op == "XOR" and o1.startswith("x"):
|
||||
(index,) = ints(o1)
|
||||
xors[index] = gate
|
||||
|
||||
p1 = run(states, gates)
|
||||
print(p1)
|
||||
|
||||
NUMBER_Z_GATES = ints(sorted(zz)[-1])[0] + 1
|
||||
# print(NUMBER_Z_GATES)
|
||||
# pprint(xors)
|
||||
|
||||
xx = [f"x{i:02}" for i in range(NUMBER_Z_GATES - 1)]
|
||||
yy = [f"y{i:02}" for i in range(NUMBER_Z_GATES - 1)]
|
||||
|
||||
# def resolve(x):
|
||||
# if x in xx or x in yy:
|
||||
# return f"{x}"
|
||||
# # return x
|
||||
# a, op, b = gate_to_in[x]
|
||||
# aa = resolve(a)
|
||||
# bb = resolve(b)
|
||||
# # print(aa, bb)
|
||||
# aa, bb = sorted([aa, bb], reverse=True)
|
||||
# op = "^" if op == "XOR" else ("|" if op == "OR" else "&")
|
||||
# return f"({aa} {op} {bb})"
|
||||
# # return [aa, op, bb]
|
||||
|
||||
|
||||
def find_xor(index):
|
||||
xor = xors[index][OUT]
|
||||
for gate in gates:
|
||||
if gate[OP] == "XOR" and (gate[LHS] == xor or gate[RHS] == xor):
|
||||
return gate
|
||||
return None
|
||||
|
||||
|
||||
corrected = []
|
||||
for i in range(NUMBER_Z_GATES):
|
||||
sx, sy, sz = [f"{c}{i:02}" for c in "xyz"]
|
||||
gate = gates[out_to_index[sz]]
|
||||
if i == 0:
|
||||
assert gate == xors[i]
|
||||
elif i == NUMBER_Z_GATES - 1:
|
||||
pass # last gate needs special check
|
||||
else:
|
||||
fixed = False
|
||||
xor = xors[i]
|
||||
if gate[OP] != "XOR":
|
||||
cgate = find_xor(i)
|
||||
assert cgate is not None
|
||||
gate[OUT], cgate[OUT] = cgate[OUT], gate[OUT]
|
||||
corrected.append(gate[OUT])
|
||||
corrected.append(cgate[OUT])
|
||||
out_to_index[gate[OUT]], out_to_index[cgate[OUT]] = (
|
||||
out_to_index[cgate[OUT]],
|
||||
out_to_index[gate[OUT]],
|
||||
)
|
||||
fixed = True
|
||||
# print(f"[swap] {gate} <-> {cgate}")
|
||||
gate = gates[out_to_index[sz]]
|
||||
assert gate[OP] == "XOR"
|
||||
|
||||
# print(gate)
|
||||
i_lhs, i_rhs = out_to_index[gate[LHS]], out_to_index[gate[RHS]]
|
||||
a, b = gates[i_lhs], gates[i_rhs]
|
||||
|
||||
if a == xor:
|
||||
# print(f"[ok] {sz} ({fixed})")
|
||||
pass
|
||||
elif b == xor:
|
||||
# print(f"[ok] {sz} ({fixed})")
|
||||
gate[0], gate[2] = gate[2], gate[0]
|
||||
else:
|
||||
if a[OP] == "AND":
|
||||
a[OUT], xor[OUT] = xor[OUT], a[OUT]
|
||||
corrected.append(a[OUT])
|
||||
corrected.append(xor[OUT])
|
||||
# print(f"[swap] {a} <-> {xor}")
|
||||
out_to_index[a[OUT]], out_to_index[xor[OUT]] = (
|
||||
out_to_index[xor[OUT]],
|
||||
out_to_index[a[OUT]],
|
||||
)
|
||||
# print(f"[ok] {sz} (manual fix)")
|
||||
else:
|
||||
print(f"[nok] {sz} (don't know how to fix)")
|
||||
|
||||
print(",".join(sorted(corrected)))
|
@ -314,5 +314,6 @@ and focus. Of course, learning more algorithms and techniques helps.
|
||||
- Day 21: `00:48:40 215 0 - - -`
|
||||
- Day 22: `00:13:04 1930 0 00:28:29 739 0`
|
||||
- Day 23: ` >24h 20096 0 >24h 17620 0`
|
||||
- Day 24:
|
||||
- Day 25:
|
||||
- Day 24: `15:57:01 17307 0 >24h 11326 0`
|
||||
- Day 25: `10:41:54 14140 0 - - -`
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user