| @@ -0,0 +1,48 @@ | |||
| def parse_grid(text): | |||
| grid = {} | |||
| for y, row in enumerate(text): | |||
| for x, v in enumerate(row): | |||
| grid[complex(x, y)] = v if v in 'SE' else ord(v) | |||
| return grid | |||
| def print_grid(mapping): | |||
| xmin, *_, xmax = {int(p.real) for p in mapping} | |||
| ymin, *_, ymax = {int(p.imag) for p in mapping} | |||
| for y in range(ymin, ymax + 1): | |||
| for x in range(xmin, xmax + 1): | |||
| print(mapping.get(complex(x, y), ' '), end=' ') | |||
| print() | |||
| def shortest_path(starts, ends, evolve): | |||
| starts = {k: [k] for k in starts} | |||
| known = starts.copy() | |||
| while starts: | |||
| old = list(starts)[0] | |||
| path = starts.pop(old) | |||
| starts |= {new: path + [new] for new in evolve(old) if new not in known} | |||
| known |= starts | |||
| for final in set(starts) & set(ends): | |||
| # print_grid({k: '.' for k in known[final]}) | |||
| return known[final] | |||
| def main(): | |||
| text = open(0).read().splitlines() | |||
| grid = parse_grid(text) | |||
| rev = {v: k for k, v in grid.items()} | |||
| start, end = rev['S'], rev['E'] | |||
| grid[start], grid[end] = ord('a'), ord('z') | |||
| dof = [1, -1, 1j, -1j] | |||
| evolve = lambda old: {old + step for step in dof if is_valid(old, step)} | |||
| is_valid = lambda old, step: old + step in grid and grid[old + step] - grid[old] <= 1 | |||
| print(len(shortest_path({start}, {end}, evolve)) - 1) | |||
| starts = {k for k, v in grid.items() if v == ord('a')} | |||
| print(len(shortest_path(starts, {end}, evolve)) - 1) | |||
| main() | |||