Solution to problem 7 in Python
This commit is contained in:
parent
ae91ce3db4
commit
b12d1031a7
134
src/Year_2015/P7.py
Normal file
134
src/Year_2015/P7.py
Normal file
@ -0,0 +1,134 @@
|
||||
# --- Day 7: Some Assembly Required ---
|
||||
|
||||
# This year, Santa brought little Bobby Tables a set of wires and bitwise logic
|
||||
# gates! Unfortunately, little Bobby is a little under the recommended age
|
||||
# range, and he needs help assembling the circuit.
|
||||
|
||||
# Each wire has an identifier (some lowercase letters) and can carry a 16-bit
|
||||
# signal (a number from 0 to 65535). A signal is provided to each wire by a
|
||||
# gate, another wire, or some specific value. Each wire can only get a signal
|
||||
# from one source, but can provide its signal to multiple destinations. A gate
|
||||
# provides no signal until all of its inputs have a signal.
|
||||
|
||||
# The included instructions booklet describes how to connect the parts
|
||||
# together: x AND y -> z means to connect wires x and y to an AND gate, and
|
||||
# then connect its output to wire z.
|
||||
|
||||
# For example:
|
||||
|
||||
# 123 -> x means that the signal 123 is provided to wire x.
|
||||
# x AND y -> z means that the bitwise AND of wire x and wire y is provided
|
||||
# to wire z.
|
||||
# p LSHIFT 2 -> q means that the value from wire p is left-shifted by 2 and
|
||||
# then provided to wire q.
|
||||
# NOT e -> f means that the bitwise complement of the value from wire e is
|
||||
# provided to wire f.
|
||||
|
||||
# Other possible gates include OR (bitwise OR) and RSHIFT (right-shift). If,
|
||||
# for some reason, you'd like to emulate the circuit instead, almost all
|
||||
# programming languages (for example, C, JavaScript, or Python) provide
|
||||
# operators for these gates.
|
||||
|
||||
# For example, here is a simple circuit:
|
||||
|
||||
# 123 -> x
|
||||
# 456 -> y
|
||||
# x AND y -> d
|
||||
# x OR y -> e
|
||||
# x LSHIFT 2 -> f
|
||||
# y RSHIFT 2 -> g
|
||||
# NOT x -> h
|
||||
# NOT y -> i
|
||||
|
||||
# After it is run, these are the signals on the wires:
|
||||
|
||||
# d: 72
|
||||
# e: 507
|
||||
# f: 492
|
||||
# g: 114
|
||||
# h: 65412
|
||||
# i: 65079
|
||||
# x: 123
|
||||
# y: 456
|
||||
|
||||
# In little Bobby's kit's instructions booklet (provided as your puzzle input),
|
||||
# what signal is ultimately provided to wire a?
|
||||
|
||||
import functools
|
||||
|
||||
with open("files/P7.txt") as f:
|
||||
instructions = [line for line in f.read().strip().split("\n")]
|
||||
|
||||
|
||||
def and_gate(x: int, y: int) -> int:
|
||||
return x & y
|
||||
|
||||
|
||||
def or_gate(x: int, y: int) -> int:
|
||||
return x | y
|
||||
|
||||
|
||||
def not_gate(x: int) -> int:
|
||||
return ~x
|
||||
|
||||
|
||||
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()
|
||||
def rec_solve(node):
|
||||
if node.isdigit():
|
||||
return int(node)
|
||||
instruction = gates[node]
|
||||
if "NOT" in instruction:
|
||||
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:
|
||||
return rec_solve(instruction[0])
|
||||
|
||||
|
||||
gates = {}
|
||||
for instr in instructions:
|
||||
lhs, rhs = instr.split(" -> ")
|
||||
gates[rhs.strip()] = lhs.strip().split()
|
||||
|
||||
|
||||
def part_1():
|
||||
signal_a = rec_solve("a")
|
||||
print(f"Signal A will be ultimately {signal_a}")
|
||||
|
||||
|
||||
# --- Part Two ---
|
||||
|
||||
# Now, take the signal you got on wire a, override wire b to that signal, and
|
||||
# reset the other wires (including wire a). What new signal is ultimately
|
||||
# provided to wire a?
|
||||
|
||||
|
||||
def part_2():
|
||||
signal_a = rec_solve("a")
|
||||
rec_solve.cache_clear()
|
||||
gates["b"] = [str(signal_a)]
|
||||
signal_b = rec_solve("a")
|
||||
print(f"Signal B will be ultimately {signal_b}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part_1()
|
||||
part_2()
|
Loading…
Reference in New Issue
Block a user