advent-of-code/2015-python/solutions/day_22.py
Anders Englöf Ytterström 5a5e843129
2015, day 16-25 (first completed calendar!) (#11)
* Solve 2015:16 "Aunt Sue"

* Make 2023:08 future compatible

Code used to work with another version of python.

* Solve 2015:17 "No such Thing as Too much"

* Solve 2015:18 "Like a GIF For Your Yard"

Also solve 2015:06 just in case, was just a ref
in the end.

* Solve 2015:19 "Medicine for Rudolph"

* Solve 2015:20 "Infinite Elves and Infinite Houses"

* Solve 2023:21 "RPG Simulator 20XX"

* Solve 2015:22 "Wizard Simulator 20XX"

* Solve 2015:23 "Opening the Turing Lock"

* Solve 2015:25 "Let it Snow"

Wrote p2rc and rc2p just for academic purposes.
Puzzles could be solved anyway.

* Solve 2015:24 "Hangs in the Balance"

---------

Co-authored-by: Anders Englöf Ytterström <anders@playmaker.ai>
2023-12-19 14:24:28 +01:00

151 lines
3.6 KiB
Python

import random
import re
from math import inf
from solutions import BaseSolution
C = {
"M": 53,
"D": 73,
"S": 113,
"P": 173,
"R": 229,
}
D = {
"S": 6,
"P": 6,
"R": 5,
}
E = {
"P": 3,
"R": 101,
"S": 7,
}
class Solution(BaseSolution):
input_file = "22.txt"
def __str__(self):
return "Day 22: Wizard Simulator 20XX"
def solve(self, pi):
o = self._solve(pi)
return o[0]
def solve_again(self, pi):
o = self._solve(pi)
return o[1]
def parse_input(self, data):
return data.strip()
def _solve(self, data):
p12 = []
boss = re.findall(r"\d+", data)
shp, smp = 50, 500
for hd in [False, True]:
x = 100_000
l = inf
for _i in range(x):
bhp, bd = [int(v) for v in boss]
t, ms = 0, 0
hp, mp = shp, smp
e = {"S": 0, "P": 0, "R": 0}
while hp > 0 and bhp > 0 and mp > 0:
if hd and t % 2 == 0:
hp -= 1
if hp == 0:
break
b = {"d": bd, "e": 0}
p = {"e": 0}
if e["P"] > 0:
e["P"] -= 1
bhp -= E["P"]
if bhp <= 0:
break
if e["R"] > 0:
e["R"] -= 1
mp += E["R"]
if e["S"] > 0:
e["S"] -= 1
p["e"] += E["S"]
if t % 2 == 0:
a = self._guess(mp, e)
if a in "RSP":
e[a] = D[a]
dp, db = self._turn(t, p, b, a)
mp -= C[a]
ms += C[a]
else:
dp, db = self._turn(t, p, b)
hp += dp
bhp += db
t += 1
if bhp <= 0 and mp >= 0:
l = min(l, ms)
p12.append(l)
assert p12[0] == 953
assert p12[1] == 1289
return p12
@staticmethod
def _guess(mp, e):
v = False
while not v:
a = random.choice("MDPRS")
match a:
case "S" | "P" | "R":
v = e[a] == 0
case _:
v = True
return a
@staticmethod
def _turn(t, p, b, a=None):
"""Take turns
>>> Solution._turn(1, {}, {"d": 5})
(-5, 0)
>>> Solution._turn(1, {}, {"d": 5, "e": -2})
(-5, -2)
>>> Solution._turn(1, {"e": 7}, {"d": 5})
(-1, 0)
>>> Solution._turn(2, {}, {}, "M")
(0, -4)
>>> Solution._turn(2, {}, {}, "D")
(2, -2)
>>> Solution._turn(2, {}, {}, "S")
(0, 0)
>>> Solution._turn(2, {}, {}, "P")
(0, 0)
>>> Solution._turn(2, {}, {}, "R")
(0, 0)
"""
ped = p.get("e", 0)
bed = b.get("e", 0)
if t % 2 == 1:
return min(ped - b["d"], -1), 0 + bed
else:
match a:
case "D":
return 2, -2
case "M":
return 0, -4
case "S":
return 0, 0
case "R":
return 0, 0
case "P":
return 0, 0
if __name__ == "__main__":
import doctest
doctest.testmod()
solution = Solution()
solution.show_results()