diff --git a/README.md b/README.md index c849953..5c8182f 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,9 @@ My solutions to the Advent of Code 2023 programming challenges. Thanks to Eric Wastl for creating this enjoyable event. -Requires `lib.py` from [aocpy](https://git.felixm.de/felixm/aocpy) repository. - -Requires `sympy` for day 24. - +- Requires `lib.py` from [aocpy](https://git.felixm.de/felixm/aocpy) repository. +- Requires `sympy` for day 24. +- Requires `matplotlib` and `networkx` for hands-on day 25. # Times @@ -40,11 +39,15 @@ Requires `sympy` for day 24. the input conjunction gate pretty early, but then messed up the implementation and thought it wasn't gonna work. Spent a half day thinking up something else before returning to the idea and it worked flawlessly. -- Day 21: +- Day 21: Part 1 was straightforward, but part 2 maybe the hardest problem this + year. - Day 22: Not too hard, but definitely way too slow for leaderboard. - Day 23: I found this fun because it required some creativity for part 2. Slow af, of course. -- Day 24: Solve problem with sympy. I first used numpy to solve part 1 and it was - much faster than using sympy, but I lost that solution when switching to sympy. - Takes about three minutes to run for part 1 and then part 2 is under a second. -- Day 25: +- Day 24: Solve problem with sympy. I first used numpy to solve part 1 and it + was much faster than using sympy, but I lost that solution when switching to + sympy. Takes about three minutes to run for part 1 and then part 2 is under a + second. +- Day 25: I cheeky solved this by plotting the graph and manually removing the + nodes. I should probably try to write an algorith that does that, but meh. + Manually plotting requires matplotlib and networkx packages. diff --git a/d25.py b/d25.py new file mode 100644 index 0000000..e5e9c81 --- /dev/null +++ b/d25.py @@ -0,0 +1,60 @@ +from lib import * + + +def plot(graph): + import networkx as nx + import matplotlib + import matplotlib.pyplot as plt + G = nx.Graph() + for node, connected_nodes in graph.items(): + for connected_node in connected_nodes: + G.add_edge(node, connected_node) + # pos = nx.spring_layout(G, k=2.0, iterations=20) # Adjust k as needed + pos = nx.shell_layout(G) + nx.draw(G, with_labels=True, node_color='lightblue', edge_color='gray', node_size=2000, font_size=15, font_weight='bold') + matplotlib.use('qtagg') + plt.show() + + +def solve_non_hands_free(input: Input, second=False): + graph = {} + for line in input.lines(): + source, targets = line.split(":") + targets = targets.strip() + targets = targets.split(" ") + + for target in targets: + if not source in graph: + graph[source] = [target] + else: + graph[source].append(target) + if not target in graph: + graph[target] = [source] + else: + graph[target].append(source) + + # plot(graph) # I used this to find the nodes that have to be removed. + to_remove = (("plt", "mgb"), ("jxm", "qns"), ("dbt", "tjd")) + for a, b in to_remove: + graph[a].remove(b) + graph[b].remove(a) + + to_visit = ["plt"] + seen = set(to_visit) + while to_visit: + node = to_visit.pop() + for nb in graph[node]: + if not nb in seen: + seen.add(nb) + to_visit.append(nb) + + return len(seen) * (len(graph) - len(seen)) + + +def main(): + DAY_INPUT = "i25.txt" + print("Solution 1:", solve_non_hands_free(Input(DAY_INPUT))) + + +if __name__ == "__main__": + main()