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