64 lines
1.5 KiB
Python
64 lines
1.5 KiB
Python
|
#!/usr/bin/env python
|
||
|
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
||
|
|
||
|
# Author: Sebastian Mark
|
||
|
# CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de)
|
||
|
|
||
|
# pylint: disable=missing-module-docstring,missing-function-docstring,consider-using-f-string
|
||
|
|
||
|
|
||
|
def readinput():
|
||
|
with open("input", "r", encoding="utf-8") as file:
|
||
|
lines = file.readlines()
|
||
|
sep = lines.index("\n")
|
||
|
|
||
|
inputs = {}
|
||
|
for line in lines[:sep]:
|
||
|
i, n = line.strip().split(": ")
|
||
|
inputs[i] = int(n)
|
||
|
|
||
|
gates = [line.strip() for line in lines[sep + 1 :]]
|
||
|
|
||
|
return inputs, gates
|
||
|
|
||
|
|
||
|
def execute(gate: str, inputs: dict) -> int:
|
||
|
a, op, b = gate.split()
|
||
|
|
||
|
try:
|
||
|
match op:
|
||
|
case "AND":
|
||
|
return inputs[a] & inputs[b]
|
||
|
case "OR":
|
||
|
return inputs[a] | inputs[b]
|
||
|
case "XOR":
|
||
|
return inputs[a] ^ inputs[b]
|
||
|
except KeyError:
|
||
|
return -1
|
||
|
|
||
|
|
||
|
def get_z(inputs: dict) -> int:
|
||
|
binary = []
|
||
|
for inp, val in sorted(inputs.items(), reverse=True):
|
||
|
if inp.startswith("z"):
|
||
|
binary.append(val)
|
||
|
return int("".join(map(str, binary)), 2)
|
||
|
|
||
|
|
||
|
def main():
|
||
|
inputs, gates = readinput()
|
||
|
|
||
|
# part 1
|
||
|
while len(gates) > 0:
|
||
|
for line in list(gates):
|
||
|
gate, new_input = line.split(" -> ")
|
||
|
res = execute(gate, inputs)
|
||
|
if res != -1:
|
||
|
inputs[new_input] = res
|
||
|
gates.remove(line)
|
||
|
print("Output of z-wires: %d" % get_z(inputs))
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|