from threading import Thread, current_thread, main_thread input_file = "input.txt" threads = [] def run_file(current_line=0, explored_lines=None, accumulator=0, switch=False): """ Run the program contained in the eponymous list. If switch is True, try and correct the program to be able to complete it on other threads. Otherwise, exit on program end or repeated instruction. :param current_line: Position to start at in the program (Program Counter) :param explored_lines: Array of already executed instructions, to detect repeats :param accumulator: Starting value of the accumulator :param switch: If True, try to switch a nop to a jmp or vice-versa to fix the program :return: True if booted successfully or if a correction allowed to boot. """ if explored_lines is None: explored_lines = list() while current_line <= len(program) - 1: if current_line in explored_lines: print(f"Instruciton at line {current_line} would have been executed twice.\n" f"The accumulator value at this point was {accumulator}") return False instruction, argument = program[current_line].split(" ") explored_lines.append(current_line) if instruction == "jmp": if switch: # Simulate nop by copying the current state and adding one the the current_line threads.append(Thread(name=str(current_line), target=run_file, args=(current_line+1, explored_lines.copy(), accumulator))) threads[-1].start() current_line += int(argument) elif instruction == "nop": if switch: # Simulate a jump by copying the current state but adding the current argument to the current_line threads.append(Thread(name=str(current_line), target=run_file, args=(current_line+int(argument), explored_lines.copy(), accumulator))) threads[-1].start() current_line += 1 elif instruction == "acc": accumulator += int(argument) current_line += 1 print(f"Booted successfully !\nThe final accumulator value was {accumulator}") if current_thread() != main_thread(): print(f"The boot was possible thanks to a modification on line {current_thread().name}") return True program = [] with open(input_file) as instructions: line = instructions.readline() while line and line != "\n": line = line.strip("\n") program.append(line) line = instructions.readline() run_file(switch=True) # Wait for children to terminate for thread in threads: thread.join()