AdventOfCode/Python/2015/22.py

178 lines
4.6 KiB
Python

from lib import *
input = read_input(2015, 22)
(*_, boss_hp), (*_, boss_damage) = map(str.split, input.splitlines())
boss_hp, boss_damage = map(int, [boss_hp, boss_damage])
player_hp = 50
player_mana = 500
def tick(*timers):
return [max(0, t - 1) for t in timers]
def fight_boss(player, boss, mana, shield_timer, poison_timer, recharge_timer):
armor = 7 if shield_timer else 0
if poison_timer:
boss -= 3
if recharge_timer:
mana += 101
shield_timer, poison_timer, recharge_timer = tick(shield_timer, poison_timer, recharge_timer)
if boss <= 0:
return 0
return fight_player(player - max(1, boss_damage - armor), boss, mana, shield_timer, poison_timer, recharge_timer)
def fight_player(player, boss, mana, shield_timer, poison_timer, recharge_timer):
if player <= 0:
return None
if poison_timer:
boss -= 3
if recharge_timer:
mana += 101
shield_timer, poison_timer, recharge_timer = tick(shield_timer, poison_timer, recharge_timer)
if boss <= 0:
return 0
out = []
# Magic Missile costs 53 mana. It instantly does 4 damage.
if (
mana >= 53
and (x := fight_boss(player, boss - 4, mana - 53, shield_timer, poison_timer, recharge_timer)) is not None
):
out.append(x + 53)
# Drain costs 73 mana. It instantly does 2 damage and heals you for 2 hit points.
if (
mana >= 73
and (x := fight_boss(player + 2, boss - 2, mana - 73, shield_timer, poison_timer, recharge_timer)) is not None
):
out.append(x + 73)
# Shield costs 113 mana. It starts an effect that lasts for 6 turns.
# While it is active, your armor is increased by 7.
if (
mana >= 113
and not shield_timer
and (x := fight_boss(player, boss, mana - 113, 6, poison_timer, recharge_timer)) is not None
):
out.append(x + 113)
# Poison costs 173 mana. It starts an effect that lasts for 6 turns.
# At the start of each turn while it is active, it deals the boss 3 damage.
if (
mana >= 173
and not poison_timer
and (x := fight_boss(player, boss, mana - 173, shield_timer, 6, recharge_timer)) is not None
):
out.append(x + 173)
# Recharge costs 229 mana. It starts an effect that lasts for 5 turns.
# At the start of each turn while it is active, it gives you 101 new mana.
if (
mana >= 229
and not recharge_timer
and (x := fight_boss(player, boss, mana - 229, shield_timer, poison_timer, 5)) is not None
):
out.append(x + 229)
return min(out, default=None)
print(fight_player(player_hp, boss_hp, player_mana, 0, 0, 0))
def fight_player(player, boss, mana, shield_timer, poison_timer, recharge_timer):
player -= 1
if player <= 0:
return None
if poison_timer:
boss -= 3
if recharge_timer:
mana += 101
shield_timer, poison_timer, recharge_timer = tick(shield_timer, poison_timer, recharge_timer)
if boss <= 0:
return 0
out = []
# Magic Missile costs 53 mana. It instantly does 4 damage.
if (
mana >= 53
and (x := fight_boss(player, boss - 4, mana - 53, shield_timer, poison_timer, recharge_timer)) is not None
):
out.append(x + 53)
# Drain costs 73 mana. It instantly does 2 damage and heals you for 2 hit points.
if (
mana >= 73
and (x := fight_boss(player + 2, boss - 2, mana - 73, shield_timer, poison_timer, recharge_timer)) is not None
):
out.append(x + 73)
# Shield costs 113 mana. It starts an effect that lasts for 6 turns.
# While it is active, your armor is increased by 7.
if (
mana >= 113
and not shield_timer
and (x := fight_boss(player, boss, mana - 113, 6, poison_timer, recharge_timer)) is not None
):
out.append(x + 113)
# Poison costs 173 mana. It starts an effect that lasts for 6 turns.
# At the start of each turn while it is active, it deals the boss 3 damage.
if (
mana >= 173
and not poison_timer
and (x := fight_boss(player, boss, mana - 173, shield_timer, 6, recharge_timer)) is not None
):
out.append(x + 173)
# Recharge costs 229 mana. It starts an effect that lasts for 5 turns.
# At the start of each turn while it is active, it gives you 101 new mana.
if (
mana >= 229
and not recharge_timer
and (x := fight_boss(player, boss, mana - 229, shield_timer, poison_timer, 5)) is not None
):
out.append(x + 229)
return min(out, default=None)
print(fight_player(player_hp, boss_hp, player_mana, 0, 0, 0))