Solution to problem 7 in Python

This commit is contained in:
David Doblas Jiménez 2022-03-10 14:27:39 +01:00
parent ae91ce3db4
commit b12d1031a7

134
src/Year_2015/P7.py Normal file
View 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()