74 lines
2.7 KiB
Python
74 lines
2.7 KiB
Python
|
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()
|