123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- #!/usr/bin/python3
- import sys
- from queue import Queue
- def print_grid(grid, as_chr=False):
- for row in grid:
- for col in row:
- print(chr(col) if as_chr else f'{col} ', end='')
- print()
- def find_start(grid, start):
- for y, row in enumerate(grid):
- for x, col in enumerate(row):
- if col == ord(start):
- return (x, y)
- return (-1, -1)
- def part1():
- start = chr(ord('a') - 1)
- end = chr(ord('z') + 1)
- grid = [[ord(c) for c in line.strip().replace('S', start).replace('E', end)] for line in sys.stdin]
- visited = [[False for col in row] for row in grid]
- steps = [[sys.maxsize for col in row] for row in grid]
- print_grid(grid, True)
- start_x, start_y = find_start(grid, start)
- max_x, max_y = len(grid[0]), len(grid)
- queue = Queue(0)
- #visited[start_y][start_x] = True
- queue.put((start_x, start_y))
- steps[start_y][start_x] = 0
- visited[start_y][start_x] = True
- while not queue.empty():
- x, y = queue.get()
- #print(x, y, chr(grid[y][x]))
- for ox, oy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
- nx, ny = x + ox, y + oy
- # skipping conditions
- if nx < 0 or ny < 0 or nx >= max_x or ny >= max_y:
- continue
- if grid[ny][nx] == ord(end):
- steps[ny][nx] = min(steps[ny][nx], steps[y][x] + 1)
- print(f'steps {steps[ny][nx]}')
- if visited[ny][nx]:
- #print(chr(grid[y][x]), chr(grid[ny][nx]))
- continue
- if grid[ny][nx] > grid[y][x] + 1:
- continue
- visited[ny][nx] = True
- steps[ny][nx] = min(steps[ny][nx], steps[y][x] + 1)
- queue.put((nx, ny))
- #print_grid(steps)
- # worst pathfinding code of my life
- # utterly lazy
- def part2():
- end = chr(ord('z') + 1)
- grid = [[ord(c) for c in line.strip().replace('E', end)] for line in sys.stdin]
- print_grid(grid, True)
- max_x, max_y = len(grid[0]), len(grid)
- starts = [[(x, y) for x, c in enumerate(row) if c == ord('a')] for y, row in enumerate(grid)]
- min_steps = []
- for row in starts:
- for start_x, start_y in row:
- #print(start_x, start_y)
- visited = [[False for col in row] for row in grid]
- steps = [[sys.maxsize for col in row] for row in grid]
- queue = Queue(0)
- #visited[start_y][start_x] = True
- queue.put((start_x, start_y))
- steps[start_y][start_x] = 0
- visited[start_y][start_x] = True
- while not queue.empty():
- x, y = queue.get()
- #print(x, y, chr(grid[y][x]))
- for ox, oy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
- nx, ny = x + ox, y + oy
- # skipping conditions
- if nx < 0 or ny < 0 or nx >= max_x or ny >= max_y:
- continue
- if grid[ny][nx] == ord(end):
- steps[ny][nx] = min(steps[ny][nx], steps[y][x] + 1)
- min_steps.append(steps[ny][nx])
- print(f'steps {steps[ny][nx]}')
- if visited[ny][nx]:
- #print(chr(grid[y][x]), chr(grid[ny][nx]))
- continue
- if grid[ny][nx] > grid[y][x] + 1:
- continue
- visited[ny][nx] = True
- steps[ny][nx] = min(steps[ny][nx], steps[y][x] + 1)
- queue.put((nx, ny))
- #print_grid(steps)
- print(min(min_steps))
- if sys.argv[1] in '1':
- part1()
- else:
- part2()
|