Skip to content
advent of code 2015

day 21

rpg simulator 20xx

approach

the shop is three hardcoded lists, and combs yields every allowed pick from each: exactly one weapon, at most one armor, up to two rings. itertools.product over the three gives every loadout, and calc_state adds up its cost, damage and armor.

the fight itself isn't simulated: battle works out how many rounds each side needs to kill the other and the player wins ties, since the player hits first. part 1 is the cheapest loadout that wins, part 2 the most expensive one that still loses. the boss stats are hardcoded at the bottom of the file.

the trick

compare rounds-to-kill for each side instead of playing the fight out.

python
def battle(bhp, bd, ba, hp, d, a):
    # boss effective damage
    bed = max(bd - a, 1)
    ped = max(d - ba, 1)

    # in how many rounds does the boss win?
    rs_b = (hp // bed) + int(hp % bd != 0)
    # in how many rounds does the player win?
    rs_p = (bhp // ped) + int(bhp % ped != 0)

    if rs_p <= rs_b:
        return True # player wins!
    return False