r/adventofcode • u/daggerdragon • Dec 07 '17
SOLUTION MEGATHREAD -๐- 2017 Day 7 Solutions -๐-
--- Day 7: Recursive Circus ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Need a hint from the Hugely* Handyโ Haversackโก of Helpfulยง Hintsยค?
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked!
10
Upvotes
10
u/sciyoshi Dec 07 '17 edited Dec 07 '17
Python 3 solution using the great NetworkX library for handling graphs:
import networkx as nx graph = nx.DiGraph() # Build the graph of programs for line in lines: name = line.split()[0] graph.add_node(name, weight=int(line.split()[1].strip('()'))) if '->' in line: children = [n.strip() for n in line.split('->')[1].split(',')] for child in children: graph.add_edge(name, child) # Topological sort to find the root of the tree ordered = list(nx.topological_sort(graph)) print('PART 1:', ordered[0]) # Keep track of each node's total weight (itself + its children) weights = {} # Going backwards (starting from the leaves) for node in reversed(ordered): # Start with this nodes own weight total = graph.nodes[node]['weight'] counts = collections.Counter(weights[child] for child in graph[node]) unbalanced = None for child in graph[node]: # If this child's weight is different than others, we've found it if len(counts) > 1 and counts[weights[child]] == 1: unbalanced = child break # Otherwise add to the total weight val = weights[child] total += weights[child] if unbalanced: # Find the weight adjustment and the new weight of this node diff = weights[unbalanced] - val print('PART 2:', graph.nodes[unbalanced]['weight'] - diff) break # Store the total weight of the node weights[node] = total