import sys input = sys.stdin map = [] for line in input: map.append(list(line.strip())) # find points where the path forks 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)) # construct a graph of paths between fork points def find_paths(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] = find_paths(p,spots) print(G) # find start position for i,c in enumerate(map[0]): if c == '.': start = (i,0) break # algorithm for finding the shortest path between points in a # a weighted directed acyclic graph # # from wikipedia: # https://en.wikipedia.org/w/index.php?title=Topological_sorting&oldid=1188428695#Application_to_shortest_path_finding # # this is a variant of the bellman-ford and shortest path faster algorithms # except we can take some shortcuts because the graph is acyclic # # we implicitly invert the weights of the graph so that, in effect, # it finds the longest path instead 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" % (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} dist[start] = 0 T = topo(G, start) for u in T: for n,v in G[u]: if dist[v] < dist[u] + n: dist[v] = dist[u] + n print(dist) print(max(dist.values()))