5 "execution_count": 133,
11 "import collections\n",
17 "execution_count": 134,
23 "def player_wins_fight(player, boss, verbose=False):\n",
24 " boss_hp = boss['hp']\n",
25 " pc_hp = player['hp']\n",
26 " while pc_hp > 0 and boss_hp > 0:\n",
27 " boss_hp -= max(player['damage'] - boss['armour'], 1)\n",
28 " pc_hp -= max(boss['damage'] - player['armour'], 1)\n",
30 " print('PC:', player['hp'], ' . Boss:', boss_hp)\n",
31 " if boss_hp <= 0:\n",
39 "execution_count": 135,
50 "execution_count": 135,
52 "output_type": "execute_result"
56 "pc = {'hp': 8, 'damage': 5, 'armour': 5}\n",
57 "boss = {'hp': 12, 'damage': 7, 'armour': 2}\n",
58 "player_wins_fight(pc, boss)"
63 "execution_count": 136,
71 "({'armour': 5, 'damage': 5, 'hp': 8}, {'armour': 2, 'damage': 7, 'hp': 12})"
74 "execution_count": 136,
76 "output_type": "execute_result"
85 "execution_count": 137,
93 "{'armour': 2, 'damage': 8, 'hp': 100}"
96 "execution_count": 137,
98 "output_type": "execute_result"
103 "for l in open('advent21.txt').readlines():\n",
104 " t, v = l.strip().split(': ')\n",
105 " if t == 'Hit Points': \n",
106 " boss['hp'] = int(v)\n",
107 " elif t == 'Armor': \n",
108 " boss['armour'] = int(v)\n",
110 " boss[t.lower()] = int(v)\n",
116 "execution_count": 138,
122 "weapons_s = \"\"\"Dagger 8 4 0\n",
123 "Shortsword 10 5 0\n",
124 "Warhammer 25 6 0\n",
125 "Longsword 40 7 0\n",
126 "Greataxe 74 8 0\"\"\"\n",
128 "armour_s = \"\"\"Leather 13 0 1\n",
129 "Chainmail 31 0 2\n",
130 "Splintmail 53 0 3\n",
131 "Bandedmail 75 0 4\n",
132 "Platemail 102 0 5\"\"\"\n",
134 "rings_s = \"\"\"Damage+1 25 1 0\n",
136 "Damage+3 100 3 0\n",
137 "Defense+1 20 0 1\n",
138 "Defense+2 40 0 2\n",
139 "Defense+3 80 0 3\"\"\""
144 "execution_count": 140,
150 "def parse_table(table):\n",
152 " for l in table.split('\\n'):\n",
154 " d += [{'name': ls[0].strip(),\n",
155 " 'cost': int(ls[1].strip()), \n",
156 " 'damage': int(ls[2].strip()), \n",
157 " 'armour': int(ls[3].strip()) }]\n",
163 "execution_count": 141,
171 "([{'armour': 0, 'cost': 8, 'damage': 4, 'name': 'Dagger'},\n",
172 " {'armour': 0, 'cost': 10, 'damage': 5, 'name': 'Shortsword'},\n",
173 " {'armour': 0, 'cost': 25, 'damage': 6, 'name': 'Warhammer'},\n",
174 " {'armour': 0, 'cost': 40, 'damage': 7, 'name': 'Longsword'},\n",
175 " {'armour': 0, 'cost': 74, 'damage': 8, 'name': 'Greataxe'}],\n",
176 " [{'armour': 1, 'cost': 13, 'damage': 0, 'name': 'Leather'},\n",
177 " {'armour': 2, 'cost': 31, 'damage': 0, 'name': 'Chainmail'},\n",
178 " {'armour': 3, 'cost': 53, 'damage': 0, 'name': 'Splintmail'},\n",
179 " {'armour': 4, 'cost': 75, 'damage': 0, 'name': 'Bandedmail'},\n",
180 " {'armour': 5, 'cost': 102, 'damage': 0, 'name': 'Platemail'},\n",
182 " [{'armour': 0, 'cost': 25, 'damage': 1, 'name': 'Damage+1'},\n",
183 " {'armour': 0, 'cost': 50, 'damage': 2, 'name': 'Damage+2'},\n",
184 " {'armour': 0, 'cost': 100, 'damage': 3, 'name': 'Damage+3'},\n",
185 " {'armour': 1, 'cost': 20, 'damage': 0, 'name': 'Defense+1'},\n",
186 " {'armour': 2, 'cost': 40, 'damage': 0, 'name': 'Defense+2'},\n",
187 " {'armour': 3, 'cost': 80, 'damage': 0, 'name': 'Defense+3'},\n",
192 "execution_count": 141,
194 "output_type": "execute_result"
198 "weapons = parse_table(weapons_s)\n",
199 "armour = parse_table(armour_s)\n",
201 "rings = parse_table(rings_s)\n",
202 "rings += [{}, {}]\n",
203 "weapons, armour, rings"
208 "execution_count": 142,
214 "def player(equipment):\n",
215 " player = {'hp': 100, 'damage': 0, 'armour': 0, 'cost': 0, 'name': ''}\n",
216 " for e in equipment:\n",
218 " player[s] += e[s]\n",
224 "execution_count": 143,
232 "{'armour': 4, 'cost': 217, 'damage': 10, 'hp': 100, 'name': ''}"
235 "execution_count": 143,
237 "output_type": "execute_result"
241 "player([{'armour': 0, 'cost': 74, 'damage': 8}, {'armour': 1, 'cost': 13, 'damage': 0},\n",
242 " {'armour': 0, 'cost': 50, 'damage': 2}, {'armour': 3, 'cost': 80, 'damage': 0}])"
247 "execution_count": 144,
258 "execution_count": 144,
260 "output_type": "execute_result"
264 "equipment = itertools.chain(\n",
265 " itertools.product(\n",
266 " itertools.combinations(weapons, 1),\n",
267 " itertools.combinations(armour, 1),\n",
268 " itertools.combinations(rings, 2)))\n",
270 "players = [player(j for i in e for j in i) for e in equipment]\n",
276 "execution_count": 146,
287 "execution_count": 146,
289 "output_type": "execute_result"
293 "winner = [p for p in players if not player_wins_fight(p, boss)]\n",
294 "# sorted(winners, key=lambda w: w['cost'])\n",
295 "min(winners, key=lambda w: w['cost'])['cost']"
299 "cell_type": "markdown",
307 "execution_count": 149,
318 "execution_count": 149,
320 "output_type": "execute_result"
324 "equipment = itertools.chain(\n",
325 " itertools.product(\n",
326 " itertools.combinations(weapons, 1),\n",
327 " itertools.combinations(armour, 1),\n",
328 " itertools.combinations(rings, 2)))\n",
330 "players = [player(j for i in e for j in i) for e in equipment]\n",
336 "execution_count": 151,
347 "execution_count": 151,
349 "output_type": "execute_result"
353 "losers = [p for p in players if not player_wins_fight(p, boss)]\n",
354 "# sorted(losers, key=lambda w: w['cost'], reverse=True)\n",
355 "max(losers, key=lambda w: w['cost'])['cost']"
360 "execution_count": null,
370 "display_name": "Python 3",
371 "language": "python",
379 "file_extension": ".py",
380 "mimetype": "text/x-python",
382 "nbconvert_exporter": "python",
383 "pygments_lexer": "ipython3",