Solution to problem 8 part 2 in Python
This commit is contained in:
parent
d44bade1e4
commit
49d870233a
90
src/P8.py
90
src/P8.py
@ -1,3 +1,5 @@
|
||||
from typing import List, Tuple
|
||||
|
||||
# --- Day 8: Handheld Halting ---
|
||||
|
||||
# Your flight to the major airline hub reaches cruising altitude without
|
||||
@ -68,16 +70,16 @@
|
||||
# executed a second time, what value is in the accumulator?
|
||||
|
||||
with open("files/P8.txt", "r") as f:
|
||||
boot_code = [code for code in f.read().strip().split("\n")]
|
||||
lines = [code for code in f.read().strip().split("\n")]
|
||||
|
||||
|
||||
def part_1() -> None:
|
||||
def part_1(lines: List[str], debug: bool = False) -> Tuple[int, bool]:
|
||||
acc = 0
|
||||
executed = []
|
||||
nline = 0
|
||||
while True:
|
||||
try:
|
||||
instr = boot_code[nline]
|
||||
instr = lines[nline]
|
||||
if nline in executed:
|
||||
# we are in a for loop :(
|
||||
break
|
||||
@ -94,10 +96,86 @@ def part_1() -> None:
|
||||
nline += 1
|
||||
continue
|
||||
except IndexError:
|
||||
print("Code has run successfully")
|
||||
if debug:
|
||||
print("Code has run successfully")
|
||||
return acc, True
|
||||
if debug:
|
||||
print(f"The value of the accumulator was {acc} before exiting")
|
||||
return acc, False
|
||||
|
||||
print(f"The value of the accumulator was {acc} before exiting")
|
||||
|
||||
# --- Part Two ---
|
||||
|
||||
# After some careful analysis, you believe that exactly one instruction is
|
||||
# corrupted.
|
||||
|
||||
# Somewhere in the program, either a jmp is supposed to be a nop, or a nop is
|
||||
# supposed to be a jmp. (No acc instructions were harmed in the corruption of
|
||||
# this boot code.)
|
||||
|
||||
# The program is supposed to terminate by attempting to execute an instruction
|
||||
# immediately after the last instruction in the file. By changing exactly one
|
||||
# jmp or nop, you can repair the boot code and make it terminate correctly.
|
||||
|
||||
# For example, consider the same program from above:
|
||||
|
||||
# nop +0
|
||||
# acc +1
|
||||
# jmp +4
|
||||
# acc +3
|
||||
# jmp -3
|
||||
# acc -99
|
||||
# acc +1
|
||||
# jmp -4
|
||||
# acc +6
|
||||
|
||||
# If you change the first instruction from nop +0 to jmp +0, it would create a
|
||||
# single-instruction infinite loop, never leaving that instruction. If you
|
||||
# change almost any of the jmp instructions, the program will still eventually
|
||||
# find another jmp instruction and loop forever.
|
||||
|
||||
# However, if you change the second-to-last instruction (from jmp -4 to
|
||||
# nop -4), the program terminates! The instructions are visited in this order:
|
||||
|
||||
# nop +0 | 1
|
||||
# acc +1 | 2
|
||||
# jmp +4 | 3
|
||||
# acc +3 |
|
||||
# jmp -3 |
|
||||
# acc -99 |
|
||||
# acc +1 | 4
|
||||
# nop -4 | 5
|
||||
# acc +6 | 6
|
||||
|
||||
# After the last instruction (acc +6), the program terminates by attempting to
|
||||
# run the instruction below the last instruction in the file. With this change,
|
||||
# after the program terminates, the accumulator contains the value 8 (acc +1,
|
||||
# acc +1, acc +6).
|
||||
|
||||
# Fix the program so that it terminates normally by changing exactly one jmp
|
||||
# (to nop) or nop (to jmp). What is the value of the accumulator after the
|
||||
# program terminates?
|
||||
|
||||
|
||||
def part_2() -> None:
|
||||
for nline, _ in enumerate(lines):
|
||||
inst = lines[nline]
|
||||
# change instructions
|
||||
if inst[:3] == "nop":
|
||||
new_inst = "jmp"
|
||||
elif inst[:3] == "jmp":
|
||||
new_inst = "nop"
|
||||
|
||||
# make a copy of the original code
|
||||
new_lines = lines.copy()
|
||||
# change line according to the instructions in the original code
|
||||
new_lines[nline] = " ".join((new_inst, inst[4:]))
|
||||
acc, has_ended = part_1(new_lines)
|
||||
if has_ended:
|
||||
print(f"The value of the accumulator was {acc} after terminates")
|
||||
break
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part_1()
|
||||
part_1(lines, debug=True)
|
||||
part_2()
|
||||
|
Loading…
Reference in New Issue
Block a user