import re
import sys
import copy
# import numpy as np
import os
from warnings import showwarning
sys.path.insert(1, os.path.abspath('../../'))
from python_tools.aoc_utils import *

def run_program(r, p):
    pc = 0
    out = 0
    while True:
        operands = [0,1,2,3,r["A"],r["B"],r["C"], 7]
        co = operands[p[pc+1]]
        lo = p[pc+1]
        match p[pc]:
            case 0:
                r["A"] = r["A"] >> co
                pc += 2
            case 1:
                r["B"] = r["B"] ^ lo
                pc += 2
            case 2:
                r["B"] = co % 8
                pc += 2
            case 3:
                if r["A"] == 0:
                    pc += 2
                else:
                    pc = lo
                return out, pc
            case 4:
                r["B"] = r["B"] ^ r["C"]
                pc += 2
            case 5:
                out = int(co % 8)
                pc += 2
            case 6:
                r["B"] = r["A"] >> co
                pc += 2
            case 7:
                r["C"] = r["A"] >> co
                pc += 2



def run(r, p):
    pc = 0
    out = []
    looping = True
    while looping:
        if pc > len(p)-1:
            looping = False
            break
        else:
            o, pc = run_program(r, p)
            out.append(o)
    return out

def recursive_run(r, c, p):
    for i in range(8):
        r_copy = r.copy()
        r_copy["A"] += i
        out = run(r_copy, p)
        if out == p:
            r["A"]+=i
            return True
        else:
            print(out,c,p)
            if out == p[c-(len(p)+1):]:
                r_copy = r.copy()
                r_copy["A"] = (r["A"]+i)<<3

                ret = recursive_run(r_copy, c-1, p)
                if ret == False:
                    continue
                else:
                    r["A"] = r_copy["A"]
                    return True
    return False





def part_one(registers, program):
    out = run(registers, program)
    print("P1: ", str(out).strip('[]').replace(" ", ""))

def part_two(r, p):
    p_copy = p.copy()
    p_copy.reverse()
    R = {"A": 0, "B": 0, "C": 0}
    if recursive_run(R, len(p), p):
        print("P2: ", R["A"])
    part_one(R, p)
    print(p)

def main():
    program = []
    registers = {}
    pos = [0,0]
    contents = file2list("input.txt")
    for row, i in enumerate(contents):
        if "Register" in i:
            a = i.split(":")
            registers[a[0].replace("Register ", "")] = int(a[1].strip())

        elif "Program" in i:
            i = i.replace("Program: ", "")
            program = list(map(int, i.split(",")))
    print(registers, program)

    part_one(registers.copy(), program)
    part_two(registers.copy(), program)


if __name__ == "__main__":
    main()