From 1802fb5df6c52b8e20c5019f819e4d934ad515a7 Mon Sep 17 00:00:00 2001 From: AKP Date: Sat, 23 Dec 2023 13:44:38 +0000 Subject: [PATCH] 2023.23 --- challenges/2023/23-aLongWalk/README.md | 6 + challenges/2023/23-aLongWalk/main.py | 222 ++++++++++++++++++++++++ challenges/2023/23-aLongWalk/tests.json | 14 ++ challenges/2023/README.md | 1 + challenges/2023/benchmark-graph.png | Bin 50627 -> 51089 bytes challenges/2023/benchmarks.jsonl | 2 + gridutil/coord.py | 2 + 7 files changed, 247 insertions(+) create mode 100644 challenges/2023/23-aLongWalk/README.md create mode 100644 challenges/2023/23-aLongWalk/main.py create mode 100644 challenges/2023/23-aLongWalk/tests.json diff --git a/challenges/2023/23-aLongWalk/README.md b/challenges/2023/23-aLongWalk/README.md new file mode 100644 index 0000000..6b64953 --- /dev/null +++ b/challenges/2023/23-aLongWalk/README.md @@ -0,0 +1,6 @@ +# [Day 23: A Long Walk](https://adventofcode.com/2023/day/23) + +Part 2 is *not*: +* 4717 (too low) +* 4826 (too low) +* 5350 (too low) \ No newline at end of file diff --git a/challenges/2023/23-aLongWalk/main.py b/challenges/2023/23-aLongWalk/main.py new file mode 100644 index 0000000..805c258 --- /dev/null +++ b/challenges/2023/23-aLongWalk/main.py @@ -0,0 +1,222 @@ +import sys +import gridutil.grid as gu +import gridutil.coord as cu +from collections import namedtuple +from collections.abc import Generator + + +def parse(instr: str) -> gu.Grid: + return gu.parse(instr) + + +def get_terminal_points(forest: gu.Grid) -> tuple[cu.Coordinate, cu.Coordinate]: + start_pos = None + end_pos = None + max_y = gu.get_max_y(forest) + for x in range(gu.get_max_x(forest) + 1): + if forest[(x, 0)] == "." and start_pos is None: + start_pos = cu.Coordinate(x, 0) + if forest[(x, max_y)] == "." and end_pos is None: + end_pos = cu.Coordinate(x, max_y) + + if start_pos is None: + raise ValueError("No open cell found on the first row of the forest") + + if end_pos is None: + raise ValueError("No open cell found on the last row of the forest") + + return start_pos, end_pos + + +def trace_path( + forest: gu.Grid, + start_pos: cu.Coordinate, + end_pos: cu.Coordinate, + history: set[cu.Coordinate] | None = None, + n: int = 0, + disallowed_moves: dict[str, cu.Direction] | None = None, +) -> int: + if history is None: + history = set() + + if disallowed_moves is None: + disallowed_moves = {} + + cursor = start_pos + while cursor != end_pos: + history.add(cursor) + allowable = [] + for direction in cu.Direction: + target_pos = cu.add(cursor, direction.delta()) + + if target_pos not in forest or target_pos in history: + continue + + val = forest[target_pos] + + if val == "#" or direction == disallowed_moves.get(val): + continue + + allowable.append(target_pos) + + n += 1 + + match len(allowable): + case 0: + return -1 + case 1: + cursor = allowable[0] + case _: + highest = max( + trace_path( + forest, + x, + end_pos, + history=history.copy(), + n=n, + disallowed_moves=disallowed_moves, + ) + for x in allowable + ) + return highest + + return n + + +def one(instr: str): + forest = parse(instr) + start_pos, end_pos = get_terminal_points(forest) + return trace_path( + forest, + start_pos, + end_pos, + disallowed_moves={ + "^": cu.Direction.Down, + "v": cu.Direction.Up, + ">": cu.Direction.Left, + "<": cu.Direction.Right, + }, + ) + + +DistanceTo: tuple[cu.Coordinate, int] = namedtuple( + "DistanceTo", ["coordinate", "distance"] +) + + +def neighbours( + forest: gu.Grid, pos: cu.Coordinate +) -> Generator[cu.Coordinate, None, None]: + for direction in cu.Direction: + target = cu.add(pos, direction.delta()) + if target not in forest or forest[target] == "#": + continue + yield target + + +def build_graph( + forest: gu.Grid, start_pos: cu.Coordinate +) -> dict[cu.Coordinate, list[DistanceTo]]: + junctions = [start_pos] + graph = {} + + while junctions: + st = junctions.pop(0) + + possible_next = list(neighbours(forest, st)) + routes = [] + + for start_point in possible_next: + n = 0 + cursor = start_point + history = set([start_point, st]) + get_next_steps = lambda: list( + filter( + lambda x: x not in history, + neighbours(forest, cursor), + ) + ) + next_steps = get_next_steps() + + while len(next_steps) == 1: + n += 1 + cursor = next_steps[0] + history.add(cursor) + next_steps = get_next_steps() + + routes.append(DistanceTo(cursor, n + 1)) + if cursor not in graph: + junctions.append(cursor) + + graph[st] = routes + + return graph + + +def display_graph(graph: dict[cu.Coordinate, list[DistanceTo]]): + import networkx as nx + import matplotlib.pyplot as plt + + G = nx.Graph() + + for node in graph: + for (end, length) in graph[node]: + G.add_edge(node, end, weight=length) + + nx.draw(G, with_labels=True, font_weight="bold") + plt.show() + + +def trace_graph_path( + graph: dict[cu.Coordinate, list[DistanceTo]], + start_pos: cu.Coordinate, + end_pos: cu.Coordinate, + history: set[cu.Coordinate] | None = None, + n: int = 0, +) -> int: + if history is None: + history = set() + + if start_pos == end_pos: + return n + + history.add(start_pos) + adjacent = list(filter(lambda x: x.coordinate not in history, graph[start_pos])) + + if len(adjacent) == 0: + return -1 + + for edge in adjacent: + if edge.coordinate == end_pos: + return edge.distance + n + + return max( + trace_graph_path( + graph, p.coordinate, end_pos, history=history.copy(), n=n + p.distance + ) + for p in adjacent + ) + + +def two(instr: str): + forest = parse(instr) + start_pos, end_pos = get_terminal_points(forest) + graph = build_graph(forest, start_pos) + # display_graph(graph) + return trace_graph_path(graph, start_pos, end_pos) + + +def _debug(*args, **kwargs): + kwargs["file"] = sys.stderr + print(*args, **kwargs) + + +if __name__ == "__main__": + if len(sys.argv) < 2 or sys.argv[1] not in ["1", "2"]: + print("Missing day argument", file=sys.stderr) + sys.exit(1) + inp = sys.stdin.read().strip() + if sys.argv[1] == "1": + print(one(inp)) + else: + print(two(inp)) diff --git a/challenges/2023/23-aLongWalk/tests.json b/challenges/2023/23-aLongWalk/tests.json new file mode 100644 index 0000000..71c7bb5 --- /dev/null +++ b/challenges/2023/23-aLongWalk/tests.json @@ -0,0 +1,14 @@ +{ + "1": [ + { + "is": "94", + "input": "#.#####################\n#.......#########...###\n#######.#########.#.###\n###.....#.>.>.###.#.###\n###v#####.#v#.###.#.###\n###.>...#.#.#.....#...#\n###v###.#.#.#########.#\n###...#.#.#.......#...#\n#####.#.#.#######.#.###\n#.....#.#.#.......#...#\n#.#####.#.#.#########v#\n#.#...#...#...###...>.#\n#.#.#v#######v###.###v#\n#...#.>.#...>.>.#.###.#\n#####v#.#.###v#.#.###.#\n#.....#...#...#.#.#...#\n#.#########.###.#.#.###\n#...###...#...#...#.###\n###.###.#.###v#####v###\n#...#...#.#.>.>.#.>.###\n#.###.###.#.###.#.#v###\n#.....###...###...#...#\n#####################.#\n\n" + } + ], + "2": [ + { + "is": "154", + "input": "#.#####################\n#.......#########...###\n#######.#########.#.###\n###.....#.>.>.###.#.###\n###v#####.#v#.###.#.###\n###.>...#.#.#.....#...#\n###v###.#.#.#########.#\n###...#.#.#.......#...#\n#####.#.#.#######.#.###\n#.....#.#.#.......#...#\n#.#####.#.#.#########v#\n#.#...#...#...###...>.#\n#.#.#v#######v###.###v#\n#...#.>.#...>.>.#.###.#\n#####v#.#.###v#.#.###.#\n#.....#...#...#.#.#...#\n#.#########.###.#.#.###\n#...###...#...#...#.###\n###.###.#.###v#####v###\n#...#...#.#.>.>.#.>.###\n#.###.###.#.###.#.#v###\n#.....###...###...#...#\n#####################.#\n\n" + } + ] +} \ No newline at end of file diff --git a/challenges/2023/README.md b/challenges/2023/README.md index 327e4d5..f7a45b9 100644 --- a/challenges/2023/README.md +++ b/challenges/2023/README.md @@ -34,3 +34,4 @@ A day denoted with a star means it has a visualisation. | 20 - Pulse Propagation | ☆ ☆ | Python | Too much reading. | | 21 - Step Counter | ★ ☆ | Python | ??? | | 22 - Sand Slabs | ★ ★ | Python | I maintain that OpenSCAD is the best AoC 3D debugging tool | +| 23 - A Long Walk | ★ ★ | Python | Both parts here could theorietcially be done with the same implementation but I couldn't be bothered to rework the part 2 solution to work for part 1 as well. | diff --git a/challenges/2023/benchmark-graph.png b/challenges/2023/benchmark-graph.png index d0e6849bc545f3238cc1decdc5edec63c10dde7b..b0561910d9b2e04fdae5965ec19612f8edafcaa3 100644 GIT binary patch literal 51089 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