summary refs log blame commit diff stats
path: root/day21.py
blob: c09cd9aa87136ce54cc5a25720f3fa071c86fc57 (plain) (tree)


























































                                                                             
#!/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))