This repository has been archived on 2024-12-22. You can view files and clone it, but cannot push or open issues or pull requests.
aoc2023/d25.py

118 lines
3.2 KiB
Python

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):
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))
from random import choice
from collections import deque
def solve(input: Input):
graph = {}
edges = {}
for line in input.lines():
src, dsts = line.split(":")
dsts = dsts.strip().split(" ")
if not src in graph:
graph[src] = []
for dst in dsts:
graph[src].append(dst)
if not dst in graph:
graph[dst] = []
graph[dst].append(src)
edge = tuple(sorted([src, dst]))
edges[edge] = 0
for i in range (1000):
first_node = choice(list(graph.keys()))
seen = set([first_node])
visit = deque([first_node])
while visit:
node = visit.popleft()
for nb in graph[node]:
if not nb in seen:
seen.add(nb)
visit.append(nb)
edge = tuple(sorted([node, nb]))
edges[edge] += 1
most_visited = sorted(edges.items(), key=lambda t: t[1], reverse=True)[:3]
# for node, count in most_visited:
# print(node, count)
for (a, b), _ in most_visited:
graph[a].remove(b)
graph[b].remove(a)
to_visit = [choice(list(graph.keys()))]
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)))
print("Solution 1:", solve(Input(DAY_INPUT)), "(hands-free)")
if __name__ == "__main__":
main()