|
1 | 1 | #!/usr/bin/env python
|
2 | 2 | import networkx as nx
|
3 | 3 |
|
4 |
| - |
5 |
| -def path(graph, source, target): |
6 |
| - try: |
7 |
| - return nx.shortest_path_length(graph, source, target) |
8 |
| - except: |
9 |
| - return -1 |
10 |
| - |
11 |
| - |
12 |
| -# fmt: off |
13 | 4 | t = {
|
14 |
| - complex(r, c): ord(s) |
| 5 | + k: ord(v) - ord("a") |
15 | 6 | for r, line in enumerate(open(0))
|
16 |
| - for c, s in enumerate(line.strip()) |
| 7 | + for c, v in enumerate(line.strip()) |
| 8 | + for k in [complex(r, c)] |
| 9 | + if (v == "S" and (s := k)) or (v == "E" and (e := k)) or True |
17 | 10 | }
|
18 |
| -# fmt: on |
19 |
| -s = next(k for k, v in t.items() if v == ord("S")) |
20 |
| -e = next(k for k, v in t.items() if v == ord("E")) |
21 |
| - |
22 |
| -t[s] = ord("a") |
23 |
| -t[e] = ord("z") |
24 |
| - |
25 |
| -G = nx.DiGraph() |
26 |
| - |
27 |
| -for k, v in t.items(): |
28 |
| - for d in (-1, 1, -1j, 1j): |
29 |
| - if (n := k + d) in t: |
30 |
| - if t[n] - v <= 1: |
31 |
| - G.add_edge(k, n) |
32 |
| - |
33 |
| -print(nx.shortest_path_length(G, s, e)) |
34 |
| -# fmt: off |
35 |
| -print(min( |
36 |
| - l |
37 |
| - for k, v in t.items() |
38 |
| - if v == ord("a") and (l := path(G, k, e)) >= 0 |
39 |
| -)) |
| 11 | +t[s], t[e] = 0, ord("z") - ord("a") |
| 12 | +G = nx.DiGraph( |
| 13 | + incoming_graph_data=( |
| 14 | + (k, n) |
| 15 | + for k, v in t.items() |
| 16 | + for d in (-1, 1, -1j, 1j) |
| 17 | + if (n := k + d) in t and t[n] - v <= 1 |
| 18 | + ) |
| 19 | +) |
| 20 | +paths = list(nx.single_target_shortest_path_length(G, e)) |
| 21 | +print(next(v for k, v in paths if k == s)) |
| 22 | +print(min(v for k, v in paths if t[k] == 0)) |
| 23 | + |
| 24 | +## BFS example, but slower than networkx |
| 25 | +# |
| 26 | +# from collections import deque |
| 27 | +# |
| 28 | +# |
| 29 | +# def bfs(t, s, e): |
| 30 | +# queue, seen = deque([(s, 0)]), set([s]) |
| 31 | +# |
| 32 | +# while queue: |
| 33 | +# k, size = queue.popleft() |
| 34 | +# |
| 35 | +# if k == e: |
| 36 | +# return size |
| 37 | +# |
| 38 | +# for d in (-1, 1, -1j, 1j): |
| 39 | +# if (n := k + d) in t and n not in seen and t[n] - t[k] <= 1: |
| 40 | +# queue.append((n, size + 1)) |
| 41 | +# seen.add(n) |
| 42 | +# |
| 43 | +# |
| 44 | +# print(bfs(t, s, e)) |
0 commit comments