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.
This commit is contained in:
parent
6aca049908
commit
9c2774be19
1 changed files with 73 additions and 0 deletions
73
2020/Day 8/Solution - with threads.py
Normal file
73
2020/Day 8/Solution - with threads.py
Normal file
|
@ -0,0 +1,73 @@
|
|||
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()
|
Loading…
Add table
Reference in a new issue