import lib EXAMPLE = """ Sabqponm abcryxxl accszExk acctuvwj abdefghi """ def neighbors_4(row, col, rows, cols): n = [] for r, c in [(1, 0), (-1, 0), (0, 1), (0, -1)]: new_row, new_col = row + r, col + c if new_row >= 0 and new_row < rows and new_col >= 0 and new_col < cols: n.append((new_row, new_col)) return n def solve(lines: list[str]): start = (0, 0) end = (0, 0) rows = len(lines) cols = len(lines[0]) heights = [] dists = [] for (row, line) in enumerate(lines): heights.append([]) dists.append([]) for (col, c) in enumerate(line): if c == 'S': start = (row, col) heights[row].append(0) dists[row].append(0) elif c == 'E': end = (row, col) heights[row].append(26) dists[row].append(2**16) else: heights[row].append(ord(lines[row][col]) - ord('a')) dists[row].append(2**16) active_fields = [start] while active_fields: row, col = active_fields.pop() current_dist = dists[row][col] current_height = heights[row][col] for row, col in neighbors_4(row, col, rows, cols): pot_height = heights[row][col] if current_height < pot_height - 1: continue if current_dist + 1 < dists[row][col]: dists[row][col] = current_dist + 1 active_fields.append((row, col)) # for row in dists: # print(row) # 34:00 return dists[end[0]][end[1]] def solve2(lines: list[str]): starts = [] all_dists =[] for (row, line) in enumerate(lines): for (col, c) in enumerate(line): if c == 'S' or c == 'a': starts.append((row, col)) for start in starts: end = (0, 0) rows = len(lines) cols = len(lines[0]) heights = [] dists = [] for (row, line) in enumerate(lines): heights.append([]) dists.append([]) for (col, c) in enumerate(line): if row == start[0] and col == start[1]: heights[row].append(0) dists[row].append(0) elif c == 'E': end = (row, col) heights[row].append(26) dists[row].append(2**16) else: heights[row].append(ord(lines[row][col]) - ord('a')) dists[row].append(2**16) active_fields = [start] while active_fields: row, col = active_fields.pop() current_dist = dists[row][col] current_height = heights[row][col] for row, col in neighbors_4(row, col, rows, cols): pot_height = heights[row][col] if current_height < pot_height - 1: continue if current_dist + 1 < dists[row][col]: dists[row][col] = current_dist + 1 active_fields.append((row, col)) all_dists.append(dists[end[0]][end[1]]) # 39:45 return min(all_dists) def main(): lines = lib.str_to_lines_no_empty(EXAMPLE) print("Example 1:", solve(lines)) lines = lib.str_to_lines_no_empty(open("i12.txt").read()) print("Solution 1:", solve(lines)) lines = lib.str_to_lines_no_empty(EXAMPLE) print("Example 2:", solve2(lines)) lines = lib.str_to_lines_no_empty(open("i12.txt").read()) print("Solution 2:", solve2(lines)) if __name__ == "__main__": main()