|
|
@@ -0,0 +1,76 @@ |
|
|
|
from collections import namedtuple |
|
|
|
import itertools |
|
|
|
|
|
|
|
|
|
|
|
def play(spell, state): |
|
|
|
is_win = 0 |
|
|
|
hp, mp, boss_hp, boss_dmg, turns, mp_spent, is_hard = state |
|
|
|
for turn in (spell, None): |
|
|
|
# prelude |
|
|
|
if turn is not None and is_hard: |
|
|
|
hp -= 1 |
|
|
|
if hp <= 0: |
|
|
|
is_win = -1 |
|
|
|
break |
|
|
|
if 'r' in turns[-5:]: |
|
|
|
mp += 101 |
|
|
|
if 'p' in turns[-6:]: |
|
|
|
boss_hp -= 3 |
|
|
|
if boss_hp <= 0: |
|
|
|
is_win = 1 |
|
|
|
break |
|
|
|
# action |
|
|
|
if turn == 'm': |
|
|
|
mp_spent += 53 |
|
|
|
boss_hp -= 4 |
|
|
|
elif turn == 'd': |
|
|
|
mp_spent += 73 |
|
|
|
boss_hp -= 2 |
|
|
|
hp += 2 |
|
|
|
elif turn == 's': |
|
|
|
mp_spent += 113 |
|
|
|
if 's' in turns[-5:]: |
|
|
|
is_win = -1 |
|
|
|
break |
|
|
|
elif turn == 'p': |
|
|
|
mp_spent += 173 |
|
|
|
if 'p' in turns[-5:]: |
|
|
|
is_win = -1 |
|
|
|
break |
|
|
|
elif turn == 'r': |
|
|
|
mp_spent += 229 |
|
|
|
if 'r' in turns[-4:]: |
|
|
|
is_win = -1 |
|
|
|
break |
|
|
|
elif turn == None: |
|
|
|
hp -= max(boss_dmg - 7 if 's' in turns[-6:] else boss_dmg, 1) |
|
|
|
turns += (turn,) |
|
|
|
# denouement |
|
|
|
if mp_spent > mp: |
|
|
|
is_win = -1 |
|
|
|
break |
|
|
|
if boss_hp <= 0: |
|
|
|
is_win = 1 |
|
|
|
break |
|
|
|
if hp <= 0: |
|
|
|
is_win = -1 |
|
|
|
break |
|
|
|
return is_win, State(hp, mp, boss_hp, boss_dmg, turns, mp_spent, is_hard) |
|
|
|
|
|
|
|
|
|
|
|
State = namedtuple('State', 'hp,mp,boss_hp,boss_dmg,turns,mp_spent,is_hard') |
|
|
|
boss_hp, boss_dmg = map(int, re.findall(r'\d+', text)) |
|
|
|
|
|
|
|
pending, wins = [State(50, 500, boss_hp, boss_dmg, tuple(), 0, False)], set() |
|
|
|
while not wins: |
|
|
|
outcomes = [play(spell, state) for state in pending for spell in 'mdspr'] |
|
|
|
wins |= {state for is_win, state in outcomes if is_win == 1} |
|
|
|
pending = [state for is_win, state in outcomes if is_win == 0] |
|
|
|
ans1 = min(win.mp_spent for win in wins) |
|
|
|
|
|
|
|
pending, wins = [State(50, 500, boss_hp, boss_dmg, tuple(), 0, True)], set() |
|
|
|
while not wins: |
|
|
|
outcomes = [play(spell, state) for state in pending for spell in 'mdspr'] |
|
|
|
wins |= {state for is_win, state in outcomes if is_win == 1} |
|
|
|
pending = [state for is_win, state in outcomes if is_win == 0] |
|
|
|
ans2 = min(win.mp_spent for win in wins) |