Advent-of-Code/2020/Day 8/Solution - with threads.py
Teo-CD 9c2774be19 2020 day 8 : alternative Python solution
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.
2020-12-21 00:46:50 +01:00

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