Mercurial > hg > aoc
view 2017/day07.d @ 24:776d882c78b8
day 18: simplify connecting threads
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Tue, 19 Dec 2017 09:37:33 -0500 |
parents | 52fdca7ea9be |
children |
line wrap: on
line source
import std.array: array, assocArray, byPair; import std.stdio; import std.algorithm: map, filter, uniq, group; import std.regex; import std.string: split; import std.conv: to; struct Node(numType) { numType weight; string[] childNames; numType[string] subweights; bool balanced; string parent; } Node!int[string] index; void parseLine(string line) { static nodeRegex = regex( r"(?P<name>\w+) \((?P<weight>\d+)\)( -> (?P<children>[\w, ]+))?" ); auto row = matchFirst(line, nodeRegex); Node!int n = { weight: to!int(row["weight"]), childNames: row["children"].split(", "), balanced: true, }; index[row["name"]] = n; } void connectNodes() { foreach(parent, node; index) { foreach(child; node.childNames) { index[child].parent = parent; } } } auto findRoot() { foreach(name, node; index) { if(!node.parent) { return name; } } return ""; } void computeSubWeights(string name) { auto node = index[name]; foreach(subname; node.childNames) { computeSubWeights(subname); auto subnode = index[subname]; auto subsum = 0; foreach(subweight; subnode.subweights) { subsum += subweight; } node.subweights[subname] = subnode.weight + subsum; } node.balanced = node.subweights.values.uniq.array.length <= 1; index[name] = node; } string findUnbalanced(string name) { auto node = index[name]; foreach(subname; node.childNames) { auto subnode = index[subname]; if(!subnode.balanced) { return findUnbalanced(subname); } } return name; } auto balanceTilty(string tilty) { auto node = index[tilty]; auto weightCounts = node.subweights.values.group.assocArray; auto badweight = weightCounts.byPair.filter!(x => x[1] == 1).array[0][0]; auto goodweight = weightCounts.byPair.filter!(x => x[1] > 1).array[0][0]; auto badname = node .subweights .byPair .filter!(x => x[1] == badweight) .array[0][0]; return index[badname].weight + (goodweight-badweight); } void main(string[] args) { foreach(line; File(args[1]).byLineCopy) { parseLine(line); } connectNodes(); auto root = findRoot(); writeln(root); computeSubWeights(root); auto tilty = findUnbalanced(root); auto balancedValue = balanceTilty(tilty); writeln(balancedValue); }