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()