adventofcode2022/day24/sol.py

130 lines
3.0 KiB
Python
Raw Normal View History

2022-12-24 17:56:22 +00:00
data = []
for line in open("input"):
data.append(line.strip())
import sys, os; sys.path.append(os.path.join(os.path.dirname(__file__), "../lib"))
import astar
#print(*data, sep="\n")
blizzards = {'>': {}, '<': {}, '^': {}, 'v': {}}
for y in range(len(data)):
for x in range(len(data[y])):
c = data[y][x]
if c in blizzards:
blizzards[c][x,y] = 1
def show(t):
H = len(data)-2
for y in range(len(data)):
s = []
W = len(data[y])-2
for x in range(len(data[y])):
c = data[y][x]
if c == '#':
s.append(c)
else:
bliz = []
u = 1 + ((x - t)-1)%W
if (u,y) in blizzards['>']:
bliz.append('>')
u = 1 + ((x + t)-1)%W
if (u,y) in blizzards['<']:
bliz.append('<')
v = 1 + ((y - t)-1)%H
if (x,v) in blizzards['v']:
bliz.append('v')
v = 1 + ((y + t)-1)%H
if (x,v) in blizzards['^']:
bliz.append('^')
if len(bliz) == 0:
s.append('.')
elif len(bliz) == 1:
s.append(bliz[0])
elif len(bliz) < 10:
s.append(str(len(bliz)))
else:
s.append('*')
print(''.join(s))
def blocked(x,y,t):
if not 0 <= y < len(data):
return True
if not 0 <= x < len(data[y]):
return True
if data[y][x] == '#':
return True
2022-12-24 18:07:38 +00:00
H = len(data)-2
W = len(data[y])-2
2022-12-24 17:56:22 +00:00
u = 1 + ((x - t)-1)%W
if (u,y) in blizzards['>']:
return True
u = 1 + ((x + t)-1)%W
if (u,y) in blizzards['<']:
return True
v = 1 + ((y - t)-1)%H
if (x,v) in blizzards['v']:
return True
v = 1 + ((y + t)-1)%H
if (x,v) in blizzards['^']:
return True
return False
2022-12-24 18:07:38 +00:00
start = (data[0].index('.'), 0)
2022-12-24 17:56:22 +00:00
goal = (data[-1].index('.'), len(data)-1)
2022-12-24 18:07:38 +00:00
leg_distance = abs(start[0] - goal[0]) + abs(start[1] - goal[1])
2022-12-24 17:56:22 +00:00
def is_goal(node):
2022-12-24 18:07:38 +00:00
x, y, t, legs = node
return (x,y) == goal and legs == 0
2022-12-24 17:56:22 +00:00
def heuristic(node):
2022-12-24 18:07:38 +00:00
x, y, t, legs = node
if legs == 0:
return 0
if legs % 2 == 1:
g = goal
else:
g = start
return (legs-1)*leg_distance + abs(g[0] - x) + abs(g[1] - y)
2022-12-24 17:56:22 +00:00
def neighbors(node):
2022-12-24 18:07:38 +00:00
x, y, t, legs = node
2022-12-24 17:56:22 +00:00
n = []
2022-12-24 18:07:38 +00:00
if legs % 2 == 1:
g = goal
else:
g = start
2022-12-24 17:56:22 +00:00
def check(dx,dy):
if not blocked(x+dx,y+dy,t+1):
2022-12-24 18:07:38 +00:00
l = legs - ((x+dx,y+dy) == g)
n.append((1, (x+dx, y+dy, t+1, l)))
2022-12-24 17:56:22 +00:00
check(+1,0)
check(0,+1)
check(-1,0)
check(0,-1)
check(0,0)
return n
show(0)
show(1)
#show((len(data)-2)*(len(data[0])-2))
2022-12-24 18:07:38 +00:00
start_node = start + (0, 1)
print(astar.search(start_node, is_goal, neighbors, heuristic))
start_node = start + (0, 3)
print(astar.search(start_node, is_goal, neighbors, heuristic))