day 24 python optimization
parent
66f2250b21
commit
0d46922957
63
day24/sol.py
63
day24/sol.py
|
@ -83,34 +83,23 @@ def blocked(x,y,t):
|
|||
return False
|
||||
|
||||
start = (data[0].index('.'), 0)
|
||||
goal = (data[-1].index('.'), len(data)-1)
|
||||
leg_distance = abs(start[0] - goal[0]) + abs(start[1] - goal[1])
|
||||
end = (data[-1].index('.'), len(data)-1)
|
||||
leg_distance = abs(start[0] - end[0]) + abs(start[1] - end[1])
|
||||
|
||||
def is_goal(node):
|
||||
x, y, t, legs = node
|
||||
return (x,y) == goal and legs == 0
|
||||
def is_goal(node, goal=end):
|
||||
x, y, t = node
|
||||
return (x,y) == goal
|
||||
|
||||
def heuristic(node):
|
||||
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)
|
||||
def heuristic(node, goal=end):
|
||||
x, y, t = node
|
||||
return abs(goal[0] - x) + abs(goal[1] - y)
|
||||
|
||||
def neighbors(node):
|
||||
x, y, t, legs = node
|
||||
x, y, t = node
|
||||
n = []
|
||||
if legs % 2 == 1:
|
||||
g = goal
|
||||
else:
|
||||
g = start
|
||||
def check(dx,dy):
|
||||
if not blocked(x+dx,y+dy,t+1):
|
||||
l = legs - ((x+dx,y+dy) == g)
|
||||
n.append((1, (x+dx, y+dy, t+1, l)))
|
||||
n.append((1, (x+dx, y+dy, t+1)))
|
||||
check(+1,0)
|
||||
check(0,+1)
|
||||
check(-1,0)
|
||||
|
@ -122,14 +111,32 @@ show(0)
|
|||
show(1)
|
||||
#show((len(data)-2)*(len(data[0])-2))
|
||||
|
||||
from functools import partial
|
||||
import time
|
||||
t0 = time.time()
|
||||
|
||||
# part 1
|
||||
d1 = astar.search(start+(0,), is_goal, neighbors, heuristic)[0]
|
||||
|
||||
t1 = time.time()
|
||||
start_node = start + (0, 1)
|
||||
print(astar.search(start_node, is_goal, neighbors, heuristic))
|
||||
|
||||
# part 2
|
||||
# we can always take the best path for each leg,
|
||||
# rather than trying to compute it over the whole trip.
|
||||
# suppose there is a better overall path B = d1' + d2 + d3
|
||||
# with d1' > d1. we can "sync up" with this path by simply
|
||||
# waiting at the end square for d1'-d1 steps at the beginning
|
||||
# of the next leg. (A* will check this possibility for us.)
|
||||
# (the start and end squares are never blocked by blizzards.)
|
||||
# therefore even if we can complete later legs faster by
|
||||
# starting later, there is no downside to taking the shortest
|
||||
# path for all the previous legs.
|
||||
is_start = partial(is_goal, goal=start)
|
||||
heuristic2 = partial(heuristic, goal=start)
|
||||
d2 = astar.search(end+(d1,), is_start, neighbors, heuristic2)[0]
|
||||
d3 = astar.search(start+(d1+d2,), is_goal, neighbors, heuristic)[0]
|
||||
|
||||
t2 = time.time()
|
||||
|
||||
start_node = start + (0, 3)
|
||||
print(astar.search(start_node, is_goal, neighbors, heuristic))
|
||||
|
||||
print("part 1", t2 - t1)
|
||||
print("part 2", time.time() - t2)
|
||||
print("part 1", d1, t1 - t0)
|
||||
print("part 2", d1+d2+d3, t2 - t0, "(%+f)"%(t2-t1))
|
||||
|
|
Loading…
Reference in New Issue