mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 12:50:32 +01:00
107 lines
2.7 KiB
Python
107 lines
2.7 KiB
Python
from __future__ import print_function, division
|
|
import heapq
|
|
|
|
def applyEffects(current):
|
|
if current['recharge'] > 0:
|
|
current['mana'] += 101
|
|
current['recharge'] -= 1
|
|
|
|
if current['shield'] > 0:
|
|
current['shield'] -= 1
|
|
|
|
if current['poison'] > 0:
|
|
current['poison'] -= 1
|
|
current['bossHP'] -= 3
|
|
|
|
|
|
def dijkstraMagic(initialState, hard):
|
|
todo = [(0, 0, initialState.copy())]
|
|
|
|
visited = {tuple(initialState.values()): 0}
|
|
iteration = 0
|
|
|
|
while todo:
|
|
iteration += 1
|
|
top = heapq.heappop(todo)
|
|
current = top[2].copy()
|
|
manaSpent = top[0]
|
|
|
|
if hard:
|
|
# Hard mode
|
|
current['hp'] -= 1
|
|
|
|
if current['hp'] <= 0:
|
|
# Already dead
|
|
continue
|
|
|
|
applyEffects(current)
|
|
|
|
if current['bossHP'] <= 0:
|
|
# We won!
|
|
return manaSpent
|
|
|
|
# Try every available spell
|
|
for spell in spells:
|
|
if current['mana'] < spell[1]:
|
|
# Not enough mana to cast
|
|
continue
|
|
|
|
if spell[4] is not None and current[spell[4]] > 0:
|
|
# Effect still active
|
|
continue
|
|
|
|
newState = current.copy()
|
|
newState['bossHP'] -= spell[2]
|
|
newState['mana'] -= spell[1]
|
|
newState['hp'] += spell[3]
|
|
if spell[4] is not None:
|
|
newState[spell[4]] = spell[5]
|
|
|
|
newMana = manaSpent + spell[1]
|
|
|
|
# Start Boss turn
|
|
applyEffects(newState)
|
|
|
|
if newState['bossHP'] > 0:
|
|
# Alive to attack?
|
|
if newState['shield'] > 0:
|
|
damage = 2
|
|
else:
|
|
damage = 9
|
|
|
|
newState['hp'] -= damage
|
|
else:
|
|
# Died during effects
|
|
return newMana
|
|
|
|
if newState['hp'] > 0:
|
|
# New state
|
|
key = tuple(newState.values())
|
|
if key not in visited or visited[key] > newMana:
|
|
# Insert the route in to the visited and queue
|
|
visited[key] = newMana
|
|
heapq.heappush(todo, (newMana, iteration, newState))
|
|
|
|
return None
|
|
|
|
spells = [
|
|
# Name, Mana, Damage, Heal, Effect, Turns
|
|
("Magic Missile", 53, 4, 0, None, 0),
|
|
("Drain", 73, 2, 2, None, 0),
|
|
("Shield", 113, 0, 0, "shield", 6),
|
|
("Poison", 173, 0, 0, "poison", 6),
|
|
("Recharge", 229, 0, 0, "recharge", 5),
|
|
]
|
|
|
|
status = {
|
|
"bossHP": 51,
|
|
"hp": 50,
|
|
"mana": 500,
|
|
"shield": 0,
|
|
"poison": 0,
|
|
"recharge": 0
|
|
}
|
|
|
|
print(dijkstraMagic(status, False))
|
|
print(dijkstraMagic(status, True))
|