Day 15 p1

master
Alfred Melch 6 years ago
parent 9eb1eb185d
commit bb66a533eb

@ -0,0 +1,202 @@
from pprint import pprint
from time import sleep
m = list()
hitpoints = dict()
with open('input.txt', 'r') as f:
for raw_line in f.readlines():
line = list()
for field in raw_line.strip():
line.append(field)
m.append(line)
for x in range(len(m)):
for y in range(len(m[x])):
if m[x][y] in ['G', 'E']:
hitpoints[(x, y)] = 200
def get_patch(pos):
x, y = pos
if x < 0 or x >= len(m):
return None
if y < 0 or y >= len(m[x]):
return None
return m[x][y]
def neighbors(pos):
return [
(pos[0], pos[1] + 1),
(pos[0], pos[1] - 1),
(pos[0] + 1, pos[1]),
(pos[0] - 1, pos[1])
]
def valid_neighbors(pos):
return [x for x in neighbors(pos) if get_patch(x) == '.']
def flood(pos):
patches = set([pos])
flood_map = {
pos: 0
}
new = set(valid_neighbors(pos))
i = 1
while new:
patches.update(new)
new_new = set()
for p in new:
flood_map[p] = i
new_new.update(valid_neighbors(p))
new = new_new - patches
i += 1
return flood_map
def get_units():
"""unit is a tuple (pos, symbol)"""
units = list()
for x in range(len(m)):
for y in range(len(m[x])):
if m[x][y] in ['G', 'E']:
units.append(((x, y), m[x][y]))
return units
def get_closest_target(flood_map, targets):
reachable_targets = {pos: dist for pos, dist in flood_map.items() if pos in targets}
if len(reachable_targets) == 0:
return None
# print('Reachable targets:', reachable_targets)
min_range = min(reachable_targets.values())
closest = [pos for pos, dist in reachable_targets.items() if dist == min_range]
# print('Closest targets:', closest)
closest.sort()
return closest[0]
def get_enemies(unit):
return [e for e in get_units() if e[1] != unit[1]]
def get_targets(unit):
targets = set()
for e in get_enemies(unit):
targets.update(valid_neighbors(e[0]))
return targets
def get_enemies_in_range(unit):
x, y = unit[0]
enemies = get_enemies(unit)
neighbors = [
(x + 1, y),
(x - 1, y),
(x, y + 1),
(x, y - 1)
]
return [e for e in enemies if e[0] in neighbors]
def move(unit, target):
move_to = dict()
neighbors = valid_neighbors(unit[0])
# print('neighbors', neighbors)
for n in neighbors:
flood_map = flood(n)
# print(n, target, flood_map.get('target'))
if target in flood_map:
move_to[n] = flood_map[target]
# print(move_to)
min_range = min(move_to.values())
closest = [pos for pos, dist in move_to.items() if dist == min_range]
closest.sort()
x1, y1 = unit[0]
x2, y2 = closest[0]
m[x1][y1] = '.'
m[x2][y2] = unit[1]
htp = hitpoints[unit[0]]
del hitpoints[unit[0]]
hitpoints[closest[0]] = htp
return (closest[0])
def count_dwarfes():
c = 0
for line in m:
for sym in line:
if sym == 'E':
c += 1
return c
def count_goblins():
c = 0
for line in m:
for sym in line:
if sym == 'G':
c += 1
return c
def print_map():
print(' ', ''.join([ str(y // 10) for y, _ in enumerate(m[0]) ]))
print(' ', ''.join([ str(y % 10) for y, _ in enumerate(m[0]) ]))
for i, line in enumerate(m):
htp_list = [(pos, htp) for pos, htp in hitpoints.items() if pos[0] == i]
htp_list.sort()
print(str(i).ljust(2), ''.join(line), [h[1] for h in htp_list])
print(' ', ''.join([ str(y % 10) for y, _ in enumerate(m[0]) ]))
print(' ', ''.join([ str(y // 10) for y, _ in enumerate(m[0]) ]))
def main():
i = 0
while 1:
print()
print(f'After {i} rounds:')
print_map()
units = get_units()
units.sort()
for u in units:
if get_patch(u[0]) != u[1]:
continue
if count_dwarfes() == 0 or count_goblins() == 0:
return i
# print(f'UNIT: {u[1]} at {u[0]}')
e = get_enemies_in_range(u)
if len(e) == 0:
# move
targets = get_targets(u)
closest = get_closest_target(flood(u[0]), targets)
if closest is None:
# print('do nothing')
continue
d = move(u, closest)
u = (d, u[1])
# print(f'Moved towards {closest} via {d}')
e = get_enemies_in_range(u)
if len(e) != 0:
# attack
atk_pos = [en[0] for en in e]
htp_map = {pos: val for pos, val in hitpoints.items() if pos in atk_pos}
min_htp = min(htp_map.values())
atk_targets = [pos for pos, htp in htp_map.items() if htp == min_htp]
target = atk_targets[0]
# print(f'Unit {u} attacking {target}')
hitpoints[target] -= 3
if hitpoints[target] <= 0:
del hitpoints[target]
x, y = target
m[x][y] = '.'
i += 1
# pprint(hitpoints)
sleep(.1)
i = main()
print()
print(f'After {i + 1} rounds:')
print_map()
print()
print('Number of complete rounds:', i)
print('hitpoints:', sum(hitpoints.values()))
print('Result', i * sum(hitpoints.values()))

@ -0,0 +1,32 @@
################################
##########################..####
#########################...####
#########################..#####
########################G..#####
#####################.#.....##.#
#####################..........#
##############.#####...........#
########G...G#.####............#
#######......G....#.....#......#
#######...G....GG.#............#
#######G.G.............####....#
#######.#.....#####....E.....###
#######......#######.G.......###
#..####..G..#########.###..#####
#........G..#########.##########
#..#..#G....#########.##########
#.###...E...#########.##########
#####...G.G.#########.##########
########G....#######..##########
####..........#####...##########
####......E........G..##########
#.G..................###########
#G...................###########
###.....##E.......E..###########
###....#............############
###.................############
##G.....#.............##########
###########...#E..##..##########
###########.E...###.E.EE.#######
###########......#.......#######
################################

@ -0,0 +1,7 @@
#######
#G..#E#
#E#E.E#
#G.##.#
#...#E#
#...E.#
#######

@ -0,0 +1,7 @@
#######
#E..EG#
#.#G.E#
#E.##E#
#G..#.#
#..E#.#
#######

@ -0,0 +1,7 @@
#######
#E.G#.#
#.#G..#
#G.#.G#
#G..#.#
#...E.#
#######

@ -0,0 +1,7 @@
#######
#.E...#
#.#..G#
#.###.#
#E#G#G#
#...#G#
#######

@ -0,0 +1,9 @@
#########
#G......#
#.E.#...#
#..##..G#
#...##..#
#...#...#
#.G...G.#
#.....G.#
#########

@ -0,0 +1,7 @@
#######
#.G...#
#...EG#
#.#.#G#
#..G#E#
#.....#
#######

@ -0,0 +1,32 @@
################################
##########..#####...############
##########.G..####..############
########.....##.##.#############
####G..#G#.......#.#############
#G.....#.GG...G.##.#############
#.#...G.......#.##..############
###..#.......#####......########
######.......#####..G....#######
######..GG..######.......#######
#####.GG....##.####G......G.####
###.............G...........####
###.#.........#####G..G....#####
###..#.##....#######E.....######
########....#########.#######..#
#########...#########.#######..#
########....#########..##......#
#########...#########...#...#.E#
#########...#########.......##.#
########....E#######.......#####
######........#####....E.#######
######.......E..E..G.E....######
#######.............###....#####
#######............####.E...####
#######...G....E##....##....####
#######...............##########
############.E.......###########
###########.....#....###########
###########.....#....###########
###########.....###.############
###########.#.##################
################################

@ -0,0 +1,9 @@
#########
#G..G..G#
#.......#
#.......#
#G..E..G#
#.......#
#.......#
#G..G..G#
#########
Loading…
Cancel
Save