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 H = len(data)-2 W = len(data[y])-2 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 start = (data[0].index('.'), 0) goal = (data[-1].index('.'), len(data)-1) leg_distance = abs(start[0] - goal[0]) + abs(start[1] - goal[1]) def is_goal(node): x, y, t, legs = node return (x,y) == goal and legs == 0 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 neighbors(node): x, y, t, legs = 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))) 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)) 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))