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