#!/usr/bin/env python
from itertools import product
from collections import namedtuple
from math import ceil
Item = namedtuple('Item', ['cost', 'damage', 'armor'])
Character = namedtuple('Character', ['hp', 'damage', 'armor'])
weapons = [
Item(8, 4, 0),
Item(10, 5, 0),
Item(25, 6, 0),
Item(40, 7, 0),
Item(74, 8, 0)
]
armor = [
Item(0, 0, 0),
Item(13, 0, 1),
Item(31, 0, 2),
Item(53, 0, 3),
Item(75, 0, 4),
Item(102, 0, 5)
]
rings = [
Item(25, 1, 0),
Item(50, 2, 0),
Item(100, 3, 0),
Item(20, 0, 1),
Item(40, 0, 2),
Item(80, 0, 3),
Item(0, 0, 0),
Item(0, 0, 0)
]
def willWin(player, boss):
playerMoves = ceil(player.hp / max(boss.damage - player.armor, 1))
bossMoves = ceil(boss.hp / max(player.damage - boss.armor, 1))
return playerMoves >= bossMoves
boss = Character(103, 9, 2)
winningCosts = []
losingCosts = []
for weapon, shield, ring1, ring2 in product(weapons, armor, rings, rings):
if ring1.cost == ring2.cost and ring1.cost != 0: continue
totalCost = weapon.cost + shield.cost + ring1.cost + ring2.cost
totalDamage = weapon.damage + shield.damage + ring1.damage + ring2.damage
totalArmor = weapon.armor + shield.armor + ring1.armor + ring2.armor
player = Character(100, totalDamage, totalArmor)
if willWin(player, boss):
winningCosts.append(totalCost)
else:
losingCosts.append(totalCost)
# part 1
print(min(winningCosts))
# part 2
print(max(losingCosts))