#! /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()