Teo-CD
9c2774be19
Solved with threads, slower by 20-30% for this workload apparently. Might be because it is the same solution, juste using a new thread for each test instead of one thread. Early exit does not seem to improve things, as the threads complete very quickly.
73 lines
2.7 KiB
Python
73 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()
|