1+ #!/usr/bin/env python
2+ # -*- coding: utf-8 -*-
3+
4+ split_data = True
5+ completed = True
6+ raw_data = None # Not To be touched
7+
8+ from heapq import heappop , heappush
9+
10+ def part1 (data ):
11+ enemy_health , enemy_damage = (int (line .split (":" )[1 ]) for line in data )
12+ # We will compensate the player for letting the boss get a free turn
13+ states = [(0 , enemy_health , 50 + enemy_damage , 500 , 0 , 0 , 0 )]
14+ # state = (used mana, enemy health, current health, current mana, shield timer, poison timer, recharge timer)
15+ while states :
16+ um , eh , ch , cm , st , pt , rt = heappop (states )
17+ if eh <= 0 :
18+ return um # Got a enemy death
19+ # BOSS's TURN
20+
21+ # Simulate the timers...
22+ if st > 0 :
23+ st -= 1
24+ ch -= max (enemy_damage - 7 , 1 )
25+ else :
26+ ch -= enemy_damage
27+ if ch <= 0 :
28+ continue # Player died
29+ if pt > 0 :
30+ pt -= 1
31+ eh -= 3
32+ if rt > 0 :
33+ rt -= 1
34+ cm += 101
35+
36+ # Player turn's timer
37+ if st > 0 :
38+ st -= 1
39+ if pt > 0 :
40+ pt -= 1
41+ eh -= 3
42+ if rt > 0 :
43+ rt -= 1
44+ cm += 101
45+
46+ for attack , cost in [("MM" , 53 ), ("D" , 73 ), ("S" , 113 ), ("P" , 173 ), ("R" , 229 )]:
47+ if cost > cm : continue
48+ if attack == "MM" :
49+ heappush (states , (um + cost ,eh - 4 ,ch ,cm - cost ,st ,pt ,rt ))
50+ elif attack == "D" :
51+ heappush (states , (um + cost ,eh - 2 ,ch + 2 ,cm - cost ,st ,pt ,rt ))
52+ elif attack == "S" and st == 0 :
53+ heappush (states , (um + cost ,eh ,ch ,cm - cost ,6 ,pt ,rt ))
54+ elif attack == "P" and pt == 0 :
55+ heappush (states , (um + cost ,eh ,ch ,cm - cost ,st ,6 ,rt ))
56+ elif attack == "R" and rt == 0 :
57+ heappush (states , (um + cost ,eh ,ch ,cm - cost ,st ,pt ,5 ))
58+
59+ def part2 (data ):
60+ enemy_health , enemy_damage = (int (line .split (":" )[1 ]) for line in data )
61+ # We will compensate the player for letting the boss get a free turn
62+ states = [(0 , enemy_health , 50 + enemy_damage , 500 , 0 , 0 , 0 )]
63+ # state = (used mana, enemy health, current health, current mana, shield timer, poison timer, recharge timer)
64+ while states :
65+ um , eh , ch , cm , st , pt , rt = heappop (states )
66+ if eh <= 0 :
67+ return um # Got a enemy death
68+ # BOSS's TURN
69+
70+ # Simulate the timers...
71+ if st > 0 :
72+ st -= 1
73+ ch -= max (enemy_damage - 7 , 1 )
74+ else :
75+ ch -= enemy_damage
76+
77+ if ch <= 0 :
78+ continue # Player died
79+
80+ if pt > 0 :
81+ pt -= 1
82+ eh -= 3
83+ if rt > 0 :
84+ rt -= 1
85+ cm += 101
86+
87+ # Player turn's timer
88+ ch -= 1
89+ if ch <= 0 :
90+ continue
91+
92+ if st > 0 :
93+ st -= 1
94+ if pt > 0 :
95+ pt -= 1
96+ eh -= 3
97+ if rt > 0 :
98+ rt -= 1
99+ cm += 101
100+
101+ for attack , cost in [("MM" , 53 ), ("D" , 73 ), ("S" , 113 ), ("P" , 173 ), ("R" , 229 )]:
102+ if cost > cm : continue
103+ if attack == "MM" :
104+ heappush (states , (um + cost ,eh - 4 ,ch ,cm - cost ,st ,pt ,rt ))
105+ elif attack == "D" :
106+ heappush (states , (um + cost ,eh - 2 ,ch + 2 ,cm - cost ,st ,pt ,rt ))
107+ elif attack == "S" and st == 0 :
108+ heappush (states , (um + cost ,eh ,ch ,cm - cost ,6 ,pt ,rt ))
109+ elif attack == "P" and pt == 0 :
110+ heappush (states , (um + cost ,eh ,ch ,cm - cost ,st ,6 ,rt ))
111+ elif attack == "R" and rt == 0 :
112+ heappush (states , (um + cost ,eh ,ch ,cm - cost ,st ,pt ,5 ))
0 commit comments