aoc-2020/d08/main.py

95 lines
2.2 KiB
Python
Executable File

#! /usr/bin/env python3
from copy import copy
sample = [
"nop +0",
"acc +1",
"jmp +4",
"acc +3",
"jmp -3",
"acc -99",
"acc +1",
"jmp -4",
"acc +6",
]
def parse_lines(lines):
def parse_line(line):
inst, _, num = line.partition(" ")
return (inst, int(num))
return [
parse_line(line)
for line in lines
]
def run_line(instructions, index):
inst, num = instructions[index]
if inst == "nop":
return index+1, 0
elif inst == "acc":
return index+1, num
elif inst == "jmp":
return index+num, 0
def part1():
with open("input.txt") as f:
instructions = parse_lines(f)
_, acc = run_until_loop(instructions, 0)
print("Total accumulated:", acc)
def run_until_loop(instructions, line, seen_lines=None):
if seen_lines is None:
seen_lines = set()
acc = 0
while line < len(instructions):
seen_lines.add(line)
# print(f"Inner: {line}:{instructions[line]}")
line, num = run_line(instructions, line)
acc += num
if line in seen_lines:
# print(f"Inner loop, break out")
return True, acc
return False, acc
def part2():
with open("input.txt") as f:
instructions = parse_lines(f)
accum = 0
line = 0
seen_lines = set()
while line < len(instructions):
if line in seen_lines:
print(f"Ugh, looping")
return
# print(f"{line}:{instructions[line]}")
inst, num = instructions[line]
if inst != "acc":
# print(f"Found an alternate, check for loop")
# Possible change
new_inst = copy(instructions)
new_seen = copy(seen_lines)
new_inst[line] = ("nop" if inst == "jmp" else "jmp", num)
has_loop, acc_d = run_until_loop(new_inst, line, new_seen)
if not has_loop:
accum += acc_d
print(f"Found solution! Changing {line}: Total {accum}")
return
seen_lines.add(line)
line, num = run_line(instructions, line)
accum += num
if __name__ == "__main__":
part1()
part2()