|
| 1 | +from collections.abc import Iterable, Container |
| 2 | + |
| 3 | +from utils.file import read_input, int_list_line |
| 4 | + |
| 5 | +falling_bytes = [complex(x,y) for x,y in (int_list_line(line, ",") for line in read_input(__package__))] |
| 6 | +start = 0j |
| 7 | +goal = 70+70j if len(falling_bytes) > 50 else 6+6j |
| 8 | + |
| 9 | +def neighbors(node: complex, walls: Container[complex]) -> Iterable[complex]: |
| 10 | + for direction in [1, -1, 1j, -1j]: |
| 11 | + neighbor = node + direction |
| 12 | + if neighbor.real < 0 or neighbor.imag < 0 or neighbor.real > goal.real or neighbor.imag > goal.imag: |
| 13 | + continue |
| 14 | + if neighbor not in walls: |
| 15 | + yield neighbor |
| 16 | + |
| 17 | +def heuristic(node: complex, goal: complex) -> int: |
| 18 | + return int(abs(node.real - goal.real) + abs(node.imag - goal.imag)) + int(abs(node.real - node.imag)) |
| 19 | + |
| 20 | +def walk(corruption_size: int) -> Iterable[tuple[list[complex], int]]: |
| 21 | + corrupted = set(falling_bytes[:corruption_size]) |
| 22 | + best_score = None |
| 23 | + visited = {start: 0} |
| 24 | + # position, score, path |
| 25 | + stack: list[tuple[complex, int, list[complex]]] = [(start, 0, [start])] |
| 26 | + while stack: |
| 27 | + stack.sort(key=lambda x: x[1] + heuristic(x[0], goal)) |
| 28 | + node, score, path = stack.pop() |
| 29 | + if score > best_score: |
| 30 | + continue |
| 31 | + visited[node] = score if node not in visited else min(score, visited[node]) |
| 32 | + for neighbor in neighbors(node, corrupted): |
| 33 | + new_score = score + 1 |
| 34 | + if neighbor == goal: |
| 35 | + #print("Path found", new_score, len(stack)) |
| 36 | + best_score = min(best_score, new_score) if best_score else new_score |
| 37 | + yield path + [neighbor], new_score |
| 38 | + if neighbor not in visited or new_score < visited[neighbor]: |
| 39 | + stack.append((neighbor, new_score, path + [neighbor])) |
| 40 | + |
| 41 | +paths = list(walk(1024)) |
| 42 | +print("Part 1:", min(score for path, score in paths)) |
0 commit comments