import sys input = sys.stdin map = [] for line in input: map.append(list(line.strip())) # construct a graph for i,c in enumerate(map[0]): if c == '.': start = (i,0) break def neighbors(x,y): n = [] c = map[y][x] for i,j in [(y-1,x),(y+1,x),(y,x-1),(y,x+1)]: if c == '<' and not j < x: continue if c == '>' and not j > x: continue if c == '^' and not i < y: continue if c == 'v' and not i > y: continue if 0 <= i < len(map) and 0 <= j < len(map[i]): if map[i][j] != '#': n.append((j,i)) return n spots = [] for i in range(len(map)): for j in range(len(map[i])): if map[i][j] == '.': n = neighbors(j,i) if len(n) not in (0,2): spots.append((j,i)) def reachable(start,spots): q = [(0,start)] dist = {} r = [] while q: q.sort() n,(x,y) = q.pop(0) if (x,y) in dist: continue dist[x,y] = n #print(x,y,neighbors(x,y)) if (x,y) in spots and (x,y) != start: r.append((n,(x,y))) else: for j,i in neighbors(x,y): if (j,i) not in dist: q.append((n+1,(j,i))) return r G = {} for p in spots: G[p] = reachable(p,spots) print(G) def topo(G, start): t = [] seen = set() tmp = set() def visit(n): if n in seen: return if n in tmp: raise Exception("cycle with %s %s" % (repr(n),tmp)) tmp.add(n) for _, p in G[n]: visit(p) tmp.remove(n) seen.add(n) t.append(n) visit(start) t.reverse() return t print("topo=",topo(G,start)) dist = {n:float('inf') for n in G} pred = {} dist[start] = 0 T = topo(G, start) for u in T: for n,v in G[u]: w = -n if dist[v] > dist[u] + w: dist[v] = dist[u] + w pred[v] = u print(dist) print(-min(dist.values())) #import astar #def goal(state): # x,y = state # return y == len(map)-1 # #M = max(n for p in G for n,_ in G[p]) # #def nb(state): # p = state # for n,q in G[p]: # yield 1+M-n, q # #n, g, path = astar.search(start, goal, nb) #print(g,path) #t = 0 #for p, q in zip(path, path[1:]): # t += sum(n for n,r in G[p] if r == q) # #print(t)