Refactoring
This commit is contained in:
1 parent
27e00613c0
commit
4b1116ccd3
1 file changed
+35
-34
+35
-34
@@ -55,58 +55,59 @@
|
|||||||
# what signal is ultimately provided to wire a?
|
# what signal is ultimately provided to wire a?
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
|
import operator
|
||||||
|
|
||||||
with open("files/P7.txt") as f:
|
with open("files/P7.txt") as f:
|
||||||
instructions = [line for line in f.read().strip().split("\n")]
|
instructions = [line for line in f.read().strip().split("\n")]
|
||||||
|
|
||||||
|
|
||||||
def and_gate(x: int, y: int) -> int:
|
OPS = {
|
||||||
return x & y
|
"ASSIGN": lambda x: x,
|
||||||
|
"NOT": operator.invert,
|
||||||
|
"AND": operator.and_,
|
||||||
|
"OR": operator.or_,
|
||||||
|
"LSHIFT": operator.lshift,
|
||||||
|
"RSHIFT": operator.rshift,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def or_gate(x: int, y: int) -> int:
|
def parse_instruction(lhs):
|
||||||
return x | y
|
tokens: list[str] = lhs.split()
|
||||||
|
|
||||||
|
if len(tokens) == 1:
|
||||||
|
return ("ASSIGN", tokens[0], None)
|
||||||
|
|
||||||
|
if len(tokens) == 2 and tokens[0] == "NOT":
|
||||||
|
return ("NOT", tokens[1], None)
|
||||||
|
|
||||||
|
if len(tokens) == 3:
|
||||||
|
left, op, right = tokens
|
||||||
|
if op in OPS:
|
||||||
|
return (op, left, right)
|
||||||
|
|
||||||
|
|
||||||
def not_gate(x: int) -> int:
|
def resolve_token(token: str) -> int:
|
||||||
return ~x
|
if token.isdigit():
|
||||||
|
return int(token) # & MASK_16BIT
|
||||||
|
return rec_solve(token)
|
||||||
def lshift_gate(x: int, y: int) -> int:
|
|
||||||
return x << y
|
|
||||||
|
|
||||||
|
|
||||||
def rshift_gate(x: int, y: int) -> int:
|
|
||||||
return x >> y
|
|
||||||
|
|
||||||
|
|
||||||
@functools.lru_cache()
|
@functools.lru_cache()
|
||||||
def rec_solve(node: str) -> int:
|
def rec_solve(node: str) -> int:
|
||||||
if node.isdigit():
|
op, left, right = gates[node]
|
||||||
return int(node)
|
|
||||||
instruction = gates[node]
|
if op in ["ASSIGN", "NOT"]:
|
||||||
if "NOT" in instruction:
|
result = OPS[op](resolve_token(left))
|
||||||
return not_gate(rec_solve(instruction[1]))
|
|
||||||
elif "AND" in instruction:
|
|
||||||
return and_gate(rec_solve(instruction[0]), rec_solve(instruction[2]))
|
|
||||||
elif "OR" in instruction:
|
|
||||||
return or_gate(rec_solve(instruction[0]), rec_solve(instruction[2]))
|
|
||||||
elif "LSHIFT" in instruction:
|
|
||||||
return lshift_gate(
|
|
||||||
rec_solve(instruction[0]), rec_solve(instruction[2])
|
|
||||||
)
|
|
||||||
elif "RSHIFT" in instruction:
|
|
||||||
return rshift_gate(
|
|
||||||
rec_solve(instruction[0]), rec_solve(instruction[2])
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
return rec_solve(instruction[0])
|
result = OPS[op](resolve_token(left), resolve_token(right))
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
gates = {}
|
gates = {}
|
||||||
for instr in instructions:
|
for instr in instructions:
|
||||||
lhs, rhs = instr.split(" -> ")
|
lhs, rhs = instr.split(" -> ")
|
||||||
gates[rhs.strip()] = lhs.strip().split()
|
gates[rhs.strip()] = parse_instruction(lhs.strip())
|
||||||
|
|
||||||
|
|
||||||
def part_1() -> None:
|
def part_1() -> None:
|
||||||
@@ -124,7 +125,7 @@ def part_1() -> None:
|
|||||||
def part_2() -> None:
|
def part_2() -> None:
|
||||||
signal_a = rec_solve("a")
|
signal_a = rec_solve("a")
|
||||||
rec_solve.cache_clear()
|
rec_solve.cache_clear()
|
||||||
gates["b"] = [str(signal_a)]
|
gates["b"] = parse_instruction(str(signal_a))
|
||||||
signal_b = rec_solve("a")
|
signal_b = rec_solve("a")
|
||||||
print(f"Signal B will be ultimately {signal_b}")
|
print(f"Signal B will be ultimately {signal_b}")
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user