1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| """CodeShell.kr — misc-checkin: BFS distances between stations.
Grid: '#' wall, '.' open, '@' entrance, '$' exit, 'A'-'T' stations. Emits a 22x22 integer matrix (0-19 = stations A-T, 20 = '@', 21 = '$').
Usage: uv run python solvers/checkin_dist.py > checkin_dist.txt """
import sys from collections import deque from pathlib import Path
GRID = "extracted/misc-checkin/floorplan.txt"
def main(): lines = [l for l in Path(GRID).read_text().splitlines() if l] h, w = len(lines), len(lines[0])
pos = {} for y, row in enumerate(lines): for x, c in enumerate(row): if c in "@$" or "A" <= c <= "T": pos[c] = (x, y)
names = [chr(ord("A") + i) for i in range(20)] + ["@", "$"] assert all(n in pos for n in names), "missing markers"
def bfs(start): dist = {start: 0} q = deque([start]) while q: x, y = q.popleft() for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)): nx, ny = x + dx, y + dy if 0 <= nx < w and 0 <= ny < h and lines[ny][nx] != "#" and (nx, ny) not in dist: dist[(nx, ny)] = dist[(x, y)] + 1 q.append((nx, ny)) return dist
cache = {n: bfs(pos[n]) for n in names} m = len(names) out = [] for a in names: row = [] for b in names: row.append(cache[a].get(pos[b], -1)) out.append(row)
for i in range(m): for j in range(m): assert out[i][j] >= 0, f"unreachable {names[i]} -> {names[j]}" assert out[i][j] == out[j][i], "asymmetric" assert all(out[i][i] == 0 for i in range(m))
print("\n".join(" ".join(str(v) for v in row) for row in out), file=sys.stdout) print(f"# stations={m}", file=sys.stderr)
if __name__ == "__main__": main()
|