Solve 2015 days 20-22.
This commit is contained in:
28
2015/d20.py
Normal file
28
2015/d20.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
from itertools import combinations
|
||||||
|
import lib
|
||||||
|
|
||||||
|
data = int(open(0).read().strip())
|
||||||
|
part_1 = False
|
||||||
|
|
||||||
|
def calc(n):
|
||||||
|
fs = lib.prime_factors(n)
|
||||||
|
vs = set([1, n])
|
||||||
|
for i in range(1, len(fs) + 1):
|
||||||
|
for c in combinations(fs, i):
|
||||||
|
p = 1
|
||||||
|
for e in c:
|
||||||
|
p *= e
|
||||||
|
vs.add(p)
|
||||||
|
r = 0
|
||||||
|
for e in vs:
|
||||||
|
if part_1:
|
||||||
|
r += e * 10
|
||||||
|
elif n <= e * 50:
|
||||||
|
r += e * 11
|
||||||
|
return r
|
||||||
|
|
||||||
|
for i in range(3, 10000000):
|
||||||
|
c = calc(i)
|
||||||
|
if c >= data:
|
||||||
|
print(i)
|
||||||
|
break
|
||||||
89
2015/d21.py
Normal file
89
2015/d21.py
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
from itertools import combinations
|
||||||
|
|
||||||
|
data = open(0).read().strip()
|
||||||
|
|
||||||
|
# hit points, damage, armor
|
||||||
|
enemy = [100, 8, 2]
|
||||||
|
|
||||||
|
weapons = [
|
||||||
|
[8, 4, 0],
|
||||||
|
[10, 5, 0],
|
||||||
|
[25, 6, 0],
|
||||||
|
[40, 7, 0],
|
||||||
|
[74, 8, 0],
|
||||||
|
]
|
||||||
|
|
||||||
|
# Armor: Cost Damage Armor
|
||||||
|
armor = [
|
||||||
|
[13, 0, 1],
|
||||||
|
[31, 0, 2],
|
||||||
|
[53, 0, 3],
|
||||||
|
[75, 0, 4],
|
||||||
|
[102, 0, 5],
|
||||||
|
]
|
||||||
|
|
||||||
|
rings = [
|
||||||
|
[25, 1, 0],
|
||||||
|
[50, 2, 0],
|
||||||
|
[100, 3, 0],
|
||||||
|
[20, 0, 1],
|
||||||
|
[40, 0, 2],
|
||||||
|
[80, 0, 3],
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def player_configs():
|
||||||
|
for wc, wd, wa in weapons:
|
||||||
|
for ac, ad, aa in armor:
|
||||||
|
for i in range(1, 3):
|
||||||
|
for rgs in combinations(rings, i):
|
||||||
|
c = wc + ac
|
||||||
|
d = wd + ad
|
||||||
|
a = wa + aa
|
||||||
|
for rc, rd, ra in rgs:
|
||||||
|
c += rc
|
||||||
|
d += rd
|
||||||
|
a += ra
|
||||||
|
yield (c, d, a)
|
||||||
|
c = wc + ac
|
||||||
|
d = wd + ad
|
||||||
|
a = wa + aa
|
||||||
|
yield (c, d, a)
|
||||||
|
for i in range(1, 3):
|
||||||
|
for rgs in combinations(rings, i):
|
||||||
|
c = wc
|
||||||
|
d = wd
|
||||||
|
a = wa
|
||||||
|
for rc, rd, ra in rgs:
|
||||||
|
c += rc
|
||||||
|
d += rd
|
||||||
|
a += ra
|
||||||
|
yield (c, d, a)
|
||||||
|
|
||||||
|
|
||||||
|
def simulate(player, enemey):
|
||||||
|
ppoints, pdamage, parmor = player
|
||||||
|
epoints, edamage, earmor = enemey
|
||||||
|
|
||||||
|
while ppoints > 0 and epoints > 0:
|
||||||
|
epoints -= max(pdamage - earmor, 1)
|
||||||
|
ppoints -= max(edamage - parmor, 1)
|
||||||
|
|
||||||
|
if epoints <= 0:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
part_1 = False
|
||||||
|
if part_1:
|
||||||
|
min_win = float("inf")
|
||||||
|
for c, d, a in player_configs():
|
||||||
|
if simulate([100, d, a], list(enemy)):
|
||||||
|
min_win = min(c, min_win)
|
||||||
|
print(min_win)
|
||||||
|
else:
|
||||||
|
max_loss = 0
|
||||||
|
for c, d, a in player_configs():
|
||||||
|
if not simulate([100, d, a], list(enemy)):
|
||||||
|
max_loss = max(c, max_loss)
|
||||||
|
print(max_loss)
|
||||||
64
2015/d22.py
Normal file
64
2015/d22.py
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
from collections import deque
|
||||||
|
|
||||||
|
min_mana_win = float("INF")
|
||||||
|
enemy_damage = 9
|
||||||
|
enemy_hit = 58
|
||||||
|
player_mana = 500
|
||||||
|
player_hit = 50
|
||||||
|
|
||||||
|
states = deque()
|
||||||
|
states.append((0, player_hit, player_mana, enemy_hit, 0, -1, -1, -1))
|
||||||
|
seen = set()
|
||||||
|
|
||||||
|
hard_mode = True
|
||||||
|
|
||||||
|
while states:
|
||||||
|
s = states.popleft()
|
||||||
|
if s in seen:
|
||||||
|
continue
|
||||||
|
seen.add(s)
|
||||||
|
player_turn, player_hit, player_mana, enemy_hit, mana_used, shield_time, poison_time, charge_time = s
|
||||||
|
|
||||||
|
if enemy_hit <= 0:
|
||||||
|
if mana_used < min_mana_win:
|
||||||
|
min_mana_win = mana_used
|
||||||
|
print(min_mana_win)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if hard_mode and player_turn == 0:
|
||||||
|
player_hit -= 1
|
||||||
|
|
||||||
|
if player_hit <= 0 or player_mana < 53 or mana_used > min_mana_win:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if poison_time >= 0:
|
||||||
|
enemy_hit -= 3
|
||||||
|
|
||||||
|
if charge_time >= 0:
|
||||||
|
player_mana += 101
|
||||||
|
|
||||||
|
if charge_time < -1:
|
||||||
|
charge_time = -1
|
||||||
|
if poison_time < -1:
|
||||||
|
poison_time = -1
|
||||||
|
if shield_time < -1:
|
||||||
|
shield_time = -1
|
||||||
|
|
||||||
|
if player_turn == 0:
|
||||||
|
for a in ["magic", "drain", "shield", "poison", "recharge"]:
|
||||||
|
if a == "magic" and player_mana >= 53:
|
||||||
|
states.append((1, player_hit, player_mana - 53, enemy_hit - 4, mana_used + 53, shield_time - 1, poison_time - 1, charge_time - 1))
|
||||||
|
elif a == "drain" and player_mana >= 73:
|
||||||
|
states.append((1, player_hit + 2, player_mana - 73, enemy_hit - 2, mana_used + 73, shield_time - 1, poison_time - 1, charge_time - 1))
|
||||||
|
elif a == "shield" and player_mana >= 113 and shield_time <= 0:
|
||||||
|
states.append((1, player_hit, player_mana - 113, enemy_hit, mana_used + 113, 6 - 1, poison_time - 1, charge_time - 1))
|
||||||
|
elif a == "poison" and player_mana >= 173 and poison_time <= 0:
|
||||||
|
states.append((1, player_hit, player_mana - 173, enemy_hit, mana_used + 173, shield_time - 1, 6 - 1, charge_time - 1))
|
||||||
|
elif a == "recharge" and player_mana >= 229 and charge_time <= 0:
|
||||||
|
states.append((1, player_hit, player_mana - 229, enemy_hit, mana_used + 229, shield_time - 1, poison_time - 1, 5 - 1))
|
||||||
|
else:
|
||||||
|
if shield_time >= 0:
|
||||||
|
player_hit -= (enemy_damage - 7)
|
||||||
|
else:
|
||||||
|
player_hit -= enemy_damage
|
||||||
|
states.append((0, player_hit, player_mana, enemy_hit, mana_used, shield_time - 1, poison_time - 1, charge_time - 1))
|
||||||
Reference in New Issue
Block a user