{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 220,
   "metadata": {},
   "outputs": [],
   "source": [
    "def decombo(operand):\n",
    "    match operand:\n",
    "        case x if x >=0 and x<=3:\n",
    "            return operand\n",
    "        case 4:\n",
    "            return rxa\n",
    "        case 5:\n",
    "            return rxb\n",
    "        case 6:\n",
    "            return rxc\n",
    "        case _:\n",
    "            raise ValueError\n",
    "\n",
    "def operation(opcode,operand, debug=False):\n",
    "    global rxa,rxb,rxc,ip,output\n",
    "    match(opcode):\n",
    "        case 0:\n",
    "            operand = decombo(operand)\n",
    "            result = int(rxa/(2**operand))\n",
    "            if debug: print(f\"adv: {rxa} / 2^{operand} = {result}\")\n",
    "            rxa = result\n",
    "            ip += 2\n",
    "        case 1:\n",
    "            result = rxb ^ operand\n",
    "            if debug: print(f\"bxl: {rxb} XOR {operand} = {result}\")\n",
    "            rxb = result\n",
    "            ip += 2\n",
    "        case 2:\n",
    "            operand = decombo(operand)\n",
    "            result = operand % 8\n",
    "            if debug: print(f\"bst: {operand} % 8 = {result}\")\n",
    "            rxb = result\n",
    "            ip += 2\n",
    "        case 3:\n",
    "            result = rxa!=0\n",
    "            if debug: print(f\"jnz: {rxa} != 0 is {result}\")\n",
    "            ip = operand if result else ip+2\n",
    "        case 4:\n",
    "            result = rxb ^ rxc\n",
    "            if debug: print(f\"bxc: {rxb} XOR {rxc} = {result}\")\n",
    "            rxb=result \n",
    "            ip += 2\n",
    "        case 5:\n",
    "            operand = decombo(operand)\n",
    "            result = operand % 8\n",
    "            if debug: print(f\"out: {operand} % 8 = {operand % 8}\")\n",
    "            output.append(f\"{result}\")\n",
    "            ip += 2\n",
    "        case 6:\n",
    "            operand = decombo(operand)\n",
    "            result = int(rxa/(2**operand))\n",
    "            if debug: print(f\"bdv: {rxa} / 2^{operand} = {result}\")\n",
    "            rxb = result\n",
    "            ip += 2\n",
    "        case 7:\n",
    "            operand = decombo(operand)\n",
    "            result = int(rxa/(2**operand))\n",
    "            if debug: print(f\"cdv: {rxa} / 2^{operand} = {result}\")\n",
    "            rxc = result\n",
    "            ip += 2\n",
    "\n",
    "\n",
    "def get_instruction(index=None):\n",
    "    if index is None:\n",
    "        index = ip\n",
    "    if index < 0 or (index+1) > len(prog):\n",
    "        return None\n",
    "    return prog[index],prog[index+1]\n",
    "\n",
    "def state():\n",
    "    print(f\"rxa: {rxa}\")\n",
    "    print(f\"rxb: {rxb}\")\n",
    "    print(f\"rxc: {rxc}\")\n",
    "    print(f\"output: {','.join(output)}\")\n",
    "    print(f\"instruction pointer : {[ip]}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 221,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "rxa: 729\n",
      "rxb: 0\n",
      "rxc: 0\n",
      "output: \n",
      "instruction pointer : [0]\n"
     ]
    }
   ],
   "source": [
    "rxa = 729\n",
    "rxb = 0\n",
    "rxc = 0\n",
    "ip = 0\n",
    "prog = [0,1,5,4,3,0]\n",
    "output = []\n",
    "state()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 222,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "rxa: 0\n",
      "rxb: 0\n",
      "rxc: 0\n",
      "output: 4,6,3,5,6,3,5,2,1,0\n",
      "instruction pointer : [6]\n"
     ]
    }
   ],
   "source": [
    "while instruction:=get_instruction():\n",
    "    operation(*instruction)\n",
    "state()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 223,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "rxa: 51342988\n",
      "rxb: 0\n",
      "rxc: 0\n",
      "output: \n",
      "instruction pointer : [0]\n"
     ]
    }
   ],
   "source": [
    "rxa = 51342988\n",
    "rxb = 0\n",
    "rxc = 0\n",
    "ip = 0\n",
    "prog = [2,4,1,3,7,5,4,0,1,3,0,3,5,5,3,0]\n",
    "output = []\n",
    "state()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 224,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "rxa: 0\n",
      "rxb: 0\n",
      "rxc: 3\n",
      "output: 1,5,7,4,1,6,0,3,0\n",
      "instruction pointer : [16]\n"
     ]
    }
   ],
   "source": [
    "while instruction:=get_instruction():\n",
    "    operation(*instruction)\n",
    "state()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for x in range(51342988):\n",
    "    rxa = x\n",
    "    rxb = 0\n",
    "    rxc = 0\n",
    "    ip = 0\n",
    "    prog = [2,4,1,3,7,5,4,0,1,3,0,3,5,5,3,0]\n",
    "    output = []\n",
    "    "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
