advent_of_code/2023/day20/part_two.py

148 lines
6.0 KiB
Python
Raw Permalink Normal View History

import copy
import math
f = open('input.txt', 'r')
# f = open('test.txt', 'r')
# f = open('test2.txt', 'r')
content = f.read()
lines = content.splitlines()
modules = {}
for line in lines:
parts = line.split(" -> ")
outputs = parts[1].replace(" ", "").split(",")
if "%" == parts[0][0]:
modules[parts[0][1:]] = {"inputs": [], "type": parts[0][0], "state": False, "outputs": outputs}
elif "&" == parts[0][0]:
modules[parts[0][1:]] = {"inputs": [], "type": parts[0][0], "in_states": {}, "outputs": outputs}
else:
modules[parts[0]] = {"inputs": [], "type": "", "outputs": outputs}
keys = list(modules.keys())
for mod in keys:
for i in modules[mod]["outputs"]:
if i in modules:
if modules[i]["type"] == "&":
modules[i]["in_states"][mod] = False
modules[i]["inputs"].append(mod)
else:
modules[i] = {"inputs": [mod], "type": "output"}
ins = [{"too": "broadcaster", "from": "button", "signal": "low"}]
outs = []
# def rec_fun(key, mod_state):
# number = 0
# if "broadcaster" == key:
# return 1
# for inputs in mod_state[key]["inputs"]:
# num_presses = rec_fun(inputs, mod_state)
# for button_presses in range(num_presses):
# ins = [{"too": "broadcaster", "from": "button", "signal": "low"}]
# while len(ins) != 0:
# # print(ins)
# # print(modules)
# outs = []
# for line in ins:
# if line["signal"] == "low":
# low_pulses += 1
# elif line["signal"] == "high":
# high_pulses += 1
# if line["too"] == "rx" and line["signal"] == "low":
# out = []
# print(button_presses)
# break
# if line["too"] not in modules: continue
# if modules[line["too"]]["type"] == "":
# for out in modules[line["too"]]["outputs"]:
# outs.append({"too": out, "from": line["too"], "signal": line["signal"]})
# elif modules[line["too"]]["type"] == "%":
# if line["signal"] == "low":
# modules[line["too"]]["state"] = not modules[line["too"]]["state"]
# sig = "high" if modules[line["too"]]["state"] else "low"
# for out in modules[line["too"]]["outputs"]:
# outs.append({"too": out, "from": line["too"], "signal": sig})
# elif modules[line["too"]]["type"] == "&":
# modules[line["too"]]["in_states"][line["from"]] = line["signal"] == "high"
# all_states_high = True
# for state in modules[line["too"]]["in_states"]:
# if modules[line["too"]]["in_states"][state] != True:
# all_states_high = False
# break
# sig = "low" if all_states_high else "high"
# for out in modules[line["too"]]["outputs"]:
# outs.append({"too": out, "from": line["too"], "signal": sig})
# ins = copy.deepcopy(outs)
# return 0
done = False
# rec_fun("rx", modules)
last_ins = []
lcm_list = []
for button_presses in range(1, 100000):
# print(last_ins)
ins = [{"too": "broadcaster", "from": "button", "signal": "low"}]
while len(ins) != 0:
# print(modules)
# print(ins)
outs = []
for line in ins:
if line["too"] == "rx" and line["signal"] == "low":
outs = []
done = True
print(button_presses)
break
# if line["too"] == "hp" and line["from"] == "rf" and line["signal"] == "high":
# if line["too"] == "hp" and line["from"] == "vq" and line["signal"] == "high":
if line["too"] == "hp" and line["signal"] == "high":
# if line["too"] == "hp" and line["from"] == "sn" and line["signal"] == "high":
outs = []
lcm_list.append(button_presses)
if len(lcm_list) == len(modules["hp"]["inputs"]):
done = True
# break
if line["too"] not in modules: continue
if modules[line["too"]]["type"] == "":
for out in modules[line["too"]]["outputs"]:
outs.append({"too": out, "from": line["too"], "signal": line["signal"]})
elif modules[line["too"]]["type"] == "%":
if line["signal"] == "low":
modules[line["too"]]["state"] = not modules[line["too"]]["state"]
sig = "high" if modules[line["too"]]["state"] else "low"
for out in modules[line["too"]]["outputs"]:
outs.append({"too": out, "from": line["too"], "signal": sig})
elif modules[line["too"]]["type"] == "&":
modules[line["too"]]["in_states"][line["from"]] = line["signal"] == "high"
all_states_high = True
for state in modules[line["too"]]["in_states"]:
if modules[line["too"]]["in_states"][state] != True:
all_states_high = False
break
sig = "low" if all_states_high else "high"
for out in modules[line["too"]]["outputs"]:
outs.append({"too": out, "from": line["too"], "signal": sig})
last_ins = copy.deepcopy(ins)
ins = copy.deepcopy(outs)
if done:
break
print(math.lcm(*lcm_list))
f.close()