Day 22
[advent-of-code-15.git] / advent22.ipynb
diff --git a/advent22.ipynb b/advent22.ipynb
new file mode 100644 (file)
index 0000000..f08ab26
--- /dev/null
@@ -0,0 +1,848 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "import copy"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[{'boss_hp': -4, 'cost': 53, 'name': 'Magic missile'},\n",
+       " {'boss_hp': -2, 'cost': 73, 'name': 'Drain', 'pc_hp': 2},\n",
+       " {'cost': 113,\n",
+       "  'name': 'Shield',\n",
+       "  'ongoing': [{'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7}]},\n",
+       " {'cost': 173,\n",
+       "  'name': 'Poison',\n",
+       "  'ongoing': [{'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3}]},\n",
+       " {'cost': 229,\n",
+       "  'name': 'Recharge',\n",
+       "  'ongoing': [{'mana': 101},\n",
+       "   {'mana': 101},\n",
+       "   {'mana': 101},\n",
+       "   {'mana': 101},\n",
+       "   {'mana': 101}]}]"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "spells = [\n",
+    "    {'name': 'Magic missile', 'cost': 53, 'boss_hp': -4},\n",
+    "    {'name': 'Drain', 'cost': 73, 'boss_hp': -2, 'pc_hp': 2},\n",
+    "    {'name': 'Shield', 'cost': 113, 'ongoing': [{'armour': 7}] * 6},\n",
+    "    {'name': 'Poison', 'cost': 173, 'ongoing': [{'boss_hp': -3}] * 6},\n",
+    "    {'name': 'Recharge', 'cost': 229, 'ongoing': [{'mana': 101}] * 5}]\n",
+    "spells"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 153,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "initial_state = {'pc_hp': 50, 'mana': 500, 'boss_hp': 58, 'boss_damage': 9, 'ongoing': [], \n",
+    "                 'spent': 0, 'cast': []}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 154,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def cast_spell(spell, state):\n",
+    "    new_state = copy.deepcopy(state)\n",
+    "    new_state['mana'] -= spell['cost']\n",
+    "    new_state['spent'] += spell['cost']\n",
+    "    new_state['cast'] += [spell['name']]\n",
+    "    if 'boss_hp' in spell:\n",
+    "        new_state['boss_hp'] += spell['boss_hp']\n",
+    "    if 'pc_hp' in spell:\n",
+    "        new_state['pc_hp'] += spell['pc_hp']\n",
+    "    if 'ongoing' in spell:\n",
+    "        new_state['ongoing'] += [spell['ongoing']]\n",
+    "    return new_state"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 155,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'boss_damage': 9,\n",
+       " 'boss_hp': 54,\n",
+       " 'cast': ['Magic missile'],\n",
+       " 'mana': 447,\n",
+       " 'ongoing': [],\n",
+       " 'pc_hp': 50,\n",
+       " 'spent': 53}"
+      ]
+     },
+     "execution_count": 155,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cast_spell(spells[0], initial_state)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 156,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'boss_damage': 9,\n",
+       " 'boss_hp': 58,\n",
+       " 'cast': [],\n",
+       " 'mana': 500,\n",
+       " 'ongoing': [],\n",
+       " 'pc_hp': 50,\n",
+       " 'spent': 0}"
+      ]
+     },
+     "execution_count": 156,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "initial_state"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 157,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'boss_damage': 9,\n",
+       " 'boss_hp': 58,\n",
+       " 'cast': ['Shield', 'Poison'],\n",
+       " 'mana': 214,\n",
+       " 'ongoing': [[{'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7}],\n",
+       "  [{'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3}]],\n",
+       " 'pc_hp': 50,\n",
+       " 'spent': 286}"
+      ]
+     },
+     "execution_count": 157,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "s2 = cast_spell(spells[2], initial_state)\n",
+    "cast_spell(spells[3], s2)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 97,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def valid_spells(spells, state):\n",
+    "    valid_spells = []\n",
+    "    for spell in spells:\n",
+    "        add_this_spell = True\n",
+    "        if spell['cost'] > state['mana']:\n",
+    "            add_this_spell = False\n",
+    "        if 'ongoing' in spell:\n",
+    "            for s in spell['ongoing'][0]:\n",
+    "                for status in state['ongoing']:\n",
+    "                    if s in status[0]:\n",
+    "                        add_this_spell = False\n",
+    "        if add_this_spell:\n",
+    "            valid_spells += [spell]\n",
+    "    return valid_spells"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 98,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[{'boss_hp': -4, 'cost': 53, 'name': 'Magic missile'},\n",
+       " {'boss_hp': -2, 'cost': 73, 'name': 'Drain', 'pc_hp': 2},\n",
+       " {'cost': 113,\n",
+       "  'name': 'Shield',\n",
+       "  'ongoing': [{'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7}]},\n",
+       " {'cost': 173,\n",
+       "  'name': 'Poison',\n",
+       "  'ongoing': [{'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3}]},\n",
+       " {'cost': 229,\n",
+       "  'name': 'Recharge',\n",
+       "  'ongoing': [{'mana': 101},\n",
+       "   {'mana': 101},\n",
+       "   {'mana': 101},\n",
+       "   {'mana': 101},\n",
+       "   {'mana': 101}]}]"
+      ]
+     },
+     "execution_count": 98,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "valid_spells(spells, initial_state)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 158,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'boss_damage': 9,\n",
+       " 'boss_hp': 58,\n",
+       " 'cast': ['Shield', 'Poison'],\n",
+       " 'mana': 214,\n",
+       " 'ongoing': [[{'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7}],\n",
+       "  [{'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3}]],\n",
+       " 'pc_hp': 50,\n",
+       " 'spent': 286}"
+      ]
+     },
+     "execution_count": 158,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "s2 = cast_spell(spells[2], initial_state)\n",
+    "s3 = cast_spell(spells[3], s2)\n",
+    "s3"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 159,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[{'boss_hp': -4, 'cost': 53, 'name': 'Magic missile'},\n",
+       " {'boss_hp': -2, 'cost': 73, 'name': 'Drain', 'pc_hp': 2}]"
+      ]
+     },
+     "execution_count": 159,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "valid_spells(spells, s3)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def boss_turn(state):\n",
+    "    new_state = apply_ongoing(state)\n",
+    "    if new_state['boss_hp'] > 0:\n",
+    "        new_state['pc_hp'] -= max(new_state['boss_damage'] - new_state['armour'], 1)\n",
+    "    return new_state"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 67,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def apply_ongoing(state):\n",
+    "    new_state = copy.deepcopy(state)\n",
+    "    new_state['armour'] = 0\n",
+    "    new_state['ongoing'] = []\n",
+    "    for status in state['ongoing']:\n",
+    "        for k in status[0]:\n",
+    "            new_state[k] += status[0][k]\n",
+    "        if len(status) > 1:\n",
+    "            new_state['ongoing'] += [status[1:]]\n",
+    "    return new_state"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 160,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'armour': 7,\n",
+       " 'boss_damage': 9,\n",
+       " 'boss_hp': 55,\n",
+       " 'cast': ['Shield', 'Poison'],\n",
+       " 'mana': 214,\n",
+       " 'ongoing': [[{'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7},\n",
+       "   {'armour': 7}],\n",
+       "  [{'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3}]],\n",
+       " 'pc_hp': 48,\n",
+       " 'spent': 286}"
+      ]
+     },
+     "execution_count": 160,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "boss_turn(s3)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 161,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'armour': 0,\n",
+       " 'boss_damage': 8,\n",
+       " 'boss_hp': 10,\n",
+       " 'cast': ['Poison'],\n",
+       " 'mana': 77,\n",
+       " 'ongoing': [[{'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3}]],\n",
+       " 'pc_hp': 2,\n",
+       " 'spent': 173}"
+      ]
+     },
+     "execution_count": 161,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "test_state_1 = {'pc_hp': 10, 'mana': 250, 'boss_hp': 13, 'boss_damage': 8, 'ongoing': [], 'spent': 0, 'cast': []}\n",
+    "s2 = cast_spell([s for s in spells if s['name'] == 'Poison'][0], test_state_1)\n",
+    "s3 = boss_turn(s2)\n",
+    "s3"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 162,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'armour': 0,\n",
+       " 'boss_damage': 8,\n",
+       " 'boss_hp': 0,\n",
+       " 'cast': ['Poison', 'Magic missile'],\n",
+       " 'mana': 24,\n",
+       " 'ongoing': [[{'boss_hp': -3}, {'boss_hp': -3}, {'boss_hp': -3}]],\n",
+       " 'pc_hp': 2,\n",
+       " 'spent': 226}"
+      ]
+     },
+     "execution_count": 162,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "s4 = apply_ongoing(s3)\n",
+    "s5 = cast_spell([s for s in spells if s['name'] == 'Magic missile'][0], s4)\n",
+    "s6 = boss_turn(s5)\n",
+    "s6"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 163,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'armour': 0,\n",
+       " 'boss_damage': 8,\n",
+       " 'boss_hp': 14,\n",
+       " 'cast': ['Recharge'],\n",
+       " 'mana': 122,\n",
+       " 'ongoing': [[{'mana': 101}, {'mana': 101}, {'mana': 101}, {'mana': 101}]],\n",
+       " 'pc_hp': 2,\n",
+       " 'spent': 229}"
+      ]
+     },
+     "execution_count": 163,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "test_state_2 = {'pc_hp': 10, 'mana': 250, 'boss_hp': 14, 'boss_damage': 8, 'ongoing': [], 'spent': 0, 'cast': []}\n",
+    "s2 = cast_spell([s for s in spells if s['name'] == 'Recharge'][0], test_state_2)\n",
+    "s3 = boss_turn(s2)\n",
+    "s3"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 164,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'armour': 7,\n",
+       " 'boss_damage': 8,\n",
+       " 'boss_hp': 14,\n",
+       " 'cast': ['Recharge', 'Shield'],\n",
+       " 'mana': 211,\n",
+       " 'ongoing': [[{'mana': 101}, {'mana': 101}],\n",
+       "  [{'armour': 7}, {'armour': 7}, {'armour': 7}, {'armour': 7}, {'armour': 7}]],\n",
+       " 'pc_hp': 1,\n",
+       " 'spent': 342}"
+      ]
+     },
+     "execution_count": 164,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "s4 = apply_ongoing(s3)\n",
+    "s5 = cast_spell([s for s in spells if s['name'] == 'Shield'][0], s4)\n",
+    "s6 = boss_turn(s5)\n",
+    "s6"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 165,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'armour': 7,\n",
+       " 'boss_damage': 8,\n",
+       " 'boss_hp': 12,\n",
+       " 'cast': ['Recharge', 'Shield', 'Drain'],\n",
+       " 'mana': 340,\n",
+       " 'ongoing': [[{'armour': 7}, {'armour': 7}, {'armour': 7}]],\n",
+       " 'pc_hp': 2,\n",
+       " 'spent': 415}"
+      ]
+     },
+     "execution_count": 165,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "s7 = apply_ongoing(s6)\n",
+    "s8 = cast_spell([s for s in spells if s['name'] == 'Drain'][0], s7)\n",
+    "s9 = boss_turn(s8)\n",
+    "s9"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 166,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'armour': 7,\n",
+       " 'boss_damage': 8,\n",
+       " 'boss_hp': 9,\n",
+       " 'cast': ['Recharge', 'Shield', 'Drain', 'Poison'],\n",
+       " 'mana': 167,\n",
+       " 'ongoing': [[{'armour': 7}],\n",
+       "  [{'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3},\n",
+       "   {'boss_hp': -3}]],\n",
+       " 'pc_hp': 1,\n",
+       " 'spent': 588}"
+      ]
+     },
+     "execution_count": 166,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "s10 = apply_ongoing(s9)\n",
+    "s11 = cast_spell([s for s in spells if s['name'] == 'Poison'][0], s10)\n",
+    "s12 = boss_turn(s11)\n",
+    "s12"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 167,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'armour': 0,\n",
+       " 'boss_damage': 8,\n",
+       " 'boss_hp': -1,\n",
+       " 'cast': ['Recharge', 'Shield', 'Drain', 'Poison', 'Magic missile'],\n",
+       " 'mana': 114,\n",
+       " 'ongoing': [[{'boss_hp': -3}, {'boss_hp': -3}, {'boss_hp': -3}]],\n",
+       " 'pc_hp': 1,\n",
+       " 'spent': 641}"
+      ]
+     },
+     "execution_count": 167,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "s13 = apply_ongoing(s12)\n",
+    "s14 = cast_spell([s for s in spells if s['name'] == 'Magic missile'][0], s13)\n",
+    "s15 = boss_turn(s14)\n",
+    "s15"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 90,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def finished(state):\n",
+    "    return state['boss_hp'] <= 0 or state['pc_hp'] <= 0\n",
+    "\n",
+    "def victory(state):\n",
+    "    return finished(state) and state['pc_hp'] > 0\n",
+    "\n",
+    "def defeat(state):\n",
+    "    return finished(state) and state['pc_hp'] <= 0"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 125,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [],
+   "source": [
+    "def ahistoric(state):\n",
+    "    return {k: state[k] for k in state if k != 'cast'}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 186,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'armour': 7,\n",
+       " 'boss_damage': 9,\n",
+       " 'boss_hp': 0,\n",
+       " 'cast': ['Poison',\n",
+       "  'Recharge',\n",
+       "  'Drain',\n",
+       "  'Poison',\n",
+       "  'Recharge',\n",
+       "  'Shield',\n",
+       "  'Poison',\n",
+       "  'Magic missile',\n",
+       "  'Magic missile'],\n",
+       " 'mana': 241,\n",
+       " 'ongoing': [[{'boss_hp': -3}, {'boss_hp': -3}]],\n",
+       " 'pc_hp': 1,\n",
+       " 'spent': 1269}"
+      ]
+     },
+     "execution_count": 186,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "agenda = [initial_state]\n",
+    "closed = []\n",
+    "while agenda:\n",
+    "        current_state = agenda[0]\n",
+    "        new_states = []\n",
+    "        if ahistoric(current_state) not in closed:\n",
+    "            closed += [ahistoric(current_state)]\n",
+    "            # print(current_state)\n",
+    "            if victory(current_state):\n",
+    "                # return current_state\n",
+    "                break\n",
+    "            for spell in valid_spells(spells, current_state):\n",
+    "                s2 = cast_spell(spell, current_state)\n",
+    "                if victory(s2):\n",
+    "                    new_states += [s2]\n",
+    "                else:\n",
+    "                    s3 = boss_turn(s2)\n",
+    "                    if victory(s3):\n",
+    "                        new_states += [s3]\n",
+    "                    if not finished(s3):\n",
+    "                        new_states += [apply_ongoing(s3)]\n",
+    "        # print(new_states)\n",
+    "        states_to_add = [s for s in new_states \n",
+    "                         if ahistoric(s) not in closed\n",
+    "                         if len(s['cast']) <= 50]\n",
+    "        agenda = sorted(states_to_add + agenda[1:], key=lambda s: s['spent'])\n",
+    "        # agenda = new_states + agenda[1:]\n",
+    "current_state"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "#Part 2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 182,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def player_bleed(state):\n",
+    "    new_state = copy.deepcopy(state)\n",
+    "    new_state['pc_hp'] -= 1\n",
+    "    return new_state"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 185,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'armour': 0,\n",
+       " 'boss_damage': 9,\n",
+       " 'boss_hp': -1,\n",
+       " 'cast': ['Poison',\n",
+       "  'Recharge',\n",
+       "  'Shield',\n",
+       "  'Poison',\n",
+       "  'Recharge',\n",
+       "  'Shield',\n",
+       "  'Poison',\n",
+       "  'Magic missile',\n",
+       "  'Magic missile'],\n",
+       " 'mana': 201,\n",
+       " 'ongoing': [[{'boss_hp': -3}]],\n",
+       " 'pc_hp': 12,\n",
+       " 'spent': 1309}"
+      ]
+     },
+     "execution_count": 185,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "agenda = [initial_state]\n",
+    "closed = []\n",
+    "while agenda:\n",
+    "        current_state = agenda[0]\n",
+    "        new_states = []\n",
+    "        if ahistoric(current_state) not in closed:\n",
+    "            closed += [ahistoric(current_state)]\n",
+    "            # print(current_state)\n",
+    "            if victory(current_state):\n",
+    "                # return current_state\n",
+    "                break\n",
+    "            for spell in valid_spells(spells, current_state):\n",
+    "                s2 = cast_spell(spell, current_state)\n",
+    "                if victory(s2):\n",
+    "                    new_states += [s2]\n",
+    "                else:\n",
+    "                    s3 = boss_turn(s2)\n",
+    "                    if victory(s3):\n",
+    "                        new_states += [s3]\n",
+    "                    s4 = player_bleed(s3)\n",
+    "                    if not finished(s4):\n",
+    "                        new_states += [apply_ongoing(s4)]\n",
+    "        # print(new_states)\n",
+    "        states_to_add = [s for s in new_states \n",
+    "                         if ahistoric(s) not in closed\n",
+    "                         if len(s['cast']) <= 50]\n",
+    "        agenda = sorted(states_to_add + agenda[1:], key=lambda s: s['spent'])\n",
+    "        # agenda = new_states + agenda[1:]\n",
+    "current_state"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "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.4.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}