From 3f9585f56ab702e9e92f6ce4d4c4f10bdc4a4e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Kope=C4=87?= <3338226+mkopec87@users.noreply.github.com> Date: Thu, 19 Dec 2024 06:44:57 +0100 Subject: [PATCH] Solutions days 23, 25 from 2023 (#20) * Solution day 23 * Solve day 25 --- src/2023/23/2023_23.py | 137 +++++++++++++++++++++++++++++++++++ src/2023/23/sample_input.txt | 5 ++ src/2023/25/2023_25.py | 47 ++++++++++++ src/2023/25/graph.png | Bin 0 -> 39439 bytes src/2023/25/sample_input.txt | 6 ++ 5 files changed, 195 insertions(+) create mode 100644 src/2023/23/2023_23.py create mode 100644 src/2023/23/sample_input.txt create mode 100644 src/2023/25/2023_25.py create mode 100644 src/2023/25/graph.png create mode 100644 src/2023/25/sample_input.txt diff --git a/src/2023/23/2023_23.py b/src/2023/23/2023_23.py new file mode 100644 index 0000000..cc9d95a --- /dev/null +++ b/src/2023/23/2023_23.py @@ -0,0 +1,137 @@ +import itertools +from typing import Tuple + +import networkx as nx +import numpy as np +from tqdm import tqdm + +from src.utils.data import load_data +from src.utils.submission import submit_or_print + +ROCK = "#" + +N = (-1, 0) +S = (1, 0) +W = (0, -1) +E = (0, 1) + + +def main(debug: bool) -> None: + input_data = load_data(debug) + + grid, start, end = parse_grid(input_data) + + result_part1 = solve_part1(grid, start, end) + result_part2 = solve_part2(grid, start, end) + + submit_or_print(result_part1, result_part2, debug) + + +def parse_grid(input_data: str) -> Tuple[np.array, Tuple[int, int], Tuple[int, int]]: + rows = [] + for line in input_data.strip().splitlines(): + rows.append(list(line)) + + # borders + rows.append(["#" for _ in rows[0]]) + rows.insert(0, ["#" for _ in rows[0]]) + + grid = np.array(rows) + + # search for start and end positions + start = 1, [y for y in range(grid.shape[1]) if grid[1, y] == "."][0] + end = ( + grid.shape[0] - 2, + [y for y in range(grid.shape[1]) if grid[grid.shape[0] - 2, y] == "."][0], + ) + + return grid, start, end + + +def solve_part1(grid: np.array, start: Tuple[int, int], end: Tuple[int, int]) -> int: + graph = create_graph(grid) + return max(map(len, nx.all_simple_paths(graph, start, end))) - 1 + + +def solve_part2(grid: np.array, start: Tuple[int, int], end: Tuple[int, int]) -> int: + graph = create_graph(grid, part2=True) + + print("Compressing graph...") + compressed_graph = compress(graph) + print("Initial graph: ", graph) + print("Compressed graph:", compressed_graph) + + viz_path = "graph.png" + pos = nx.planar_layout(compressed_graph) + nx.draw(compressed_graph, pos, with_labels=True) + import matplotlib.pyplot as plt + + plt.savefig(viz_path) + print(f"Saved compressed graph visualization to: {viz_path}") + + print("Searching for longest path in compressed graph...") + return max( + map( + lambda path: nx.path_weight(compressed_graph, path, "weight"), + nx.all_simple_paths(compressed_graph, start, end), + ) + ) + + +def create_graph(grid: np.array, part2: bool = False) -> nx.Graph: + graph = nx.Graph() if part2 else nx.DiGraph() + for x, y in np.ndindex(grid.shape): + if grid[x, y] != ROCK: + graph.add_node((x, y)) + for x, y in np.ndindex(grid.shape): + p = grid[x, y] + if p != ROCK: + if part2: + p = "." + + match p: + case ">": + dirs = [E] + case "<": + dirs = [W] + case "^": + dirs = [N] + case "v": + dirs = [S] + case _: + dirs = [N, S, W, E] + + for d in dirs: + n_pos = d[0] + x, d[1] + y + n = grid[n_pos] + if n != ROCK: + graph.add_edge((x, y), n_pos, weight=1) + return graph + + +def compress(graph: nx.Graph) -> nx.Graph: + crossroads = {node for node in graph.nodes if len(graph.edges(node)) != 2} + + compressed_graph = nx.Graph(graph) + for p1, p2 in tqdm(list(itertools.combinations(crossroads, 2))): + # simplified graph without crossroads + graph_copy = nx.Graph(graph) + for c in crossroads: + if c not in {p1, p2}: + graph_copy.remove_node(c) + + # find all paths + for path in nx.all_simple_paths(graph_copy, p1, p2): + if len(path) < 3: + continue + weight = len(path) - 1 + compressed_graph.add_edge(p1, p2, weight=weight) + for n in path[1:-1]: + compressed_graph.remove_node(n) + return compressed_graph + + +if __name__ == "__main__": + debug_mode = True + # debug_mode = False + main(debug_mode) diff --git a/src/2023/23/sample_input.txt b/src/2023/23/sample_input.txt new file mode 100644 index 0000000..1f7a210 --- /dev/null +++ b/src/2023/23/sample_input.txt @@ -0,0 +1,5 @@ +#.####### +#>......# +#.###.#.# +#....>..# +#######.# diff --git a/src/2023/25/2023_25.py b/src/2023/25/2023_25.py new file mode 100644 index 0000000..0aac051 --- /dev/null +++ b/src/2023/25/2023_25.py @@ -0,0 +1,47 @@ +import math +import re + +import matplotlib.pyplot as plt +import networkx as nx + +from src.utils.data import load_data +from src.utils.submission import submit_or_print + + +def main(debug: bool) -> None: + input_data = load_data(debug) + + graph = parse_graph(input_data) + print(graph) + + viz_path = "graph.png" + pos = nx.spring_layout(graph) + nx.draw(graph, pos, with_labels=True) + plt.savefig(viz_path) + print(f"Saved graph visualization to: {viz_path}") + + edges = nx.edge_betweenness_centrality(graph) + top3 = sorted(edges.items(), key=lambda k: k[1], reverse=True)[:3] + for e, _ in top3: + graph.remove_edge(*e) + print(f"Removed 3 key edges: {[t[0] for t in top3]}") + + result_part1 = math.prod([len(c) for c in nx.connected_components(graph)]) + result_part2 = None + + submit_or_print(result_part1, result_part2, debug) + + +def parse_graph(input_data: str) -> nx.Graph: + graph = nx.Graph() + for line in input_data.strip().splitlines(): + nodes = re.findall(r"[a-z]+", line) + for node in nodes[1:]: + graph.add_edge(nodes[0], node) + return graph + + +if __name__ == "__main__": + debug_mode = True + # debug_mode = False + main(debug_mode) diff --git a/src/2023/25/graph.png b/src/2023/25/graph.png new file mode 100644 index 0000000000000000000000000000000000000000..11b49c972f0886e06c272b12aed6a8b99a83248d GIT binary patch literal 39439 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