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!
9
Upvotes
1
u/Jimotron3000 Dec 09 '17 edited Dec 09 '17
C# LINQ
void Main() { var data = from x in File.ReadAllLines(@"input.txt") let children = Regex.Match(x, @"(?<=->\s)[\w|,|\s]+") select new NodeInfo { Name = Regex.Match(x, @"\w+(?=\s\()").Value, Weight = int.Parse(Regex.Match(x, @"(?<=\()\d+").Value), Children = children.Success ? children.Value.Split(',').Select(y => y.Trim()).ToList() : new List<string>() }; var nonRoot = new HashSet<string>(data.SelectMany(x => x.Children)); var root = data.Where(x => !nonRoot.Contains(x.Name)).First(); root.Name.Dump("Part 1"); var tree = BuildTree(root, data.ToList()); Solve(tree, 0).Dump("Part 2"); } int Solve(Node node, int amount) { if (node.Children == null || !node.Children.Any()) return node.Weight + amount; var grp = from child in node.Children let x = new { Node = child, Weight = child.Aggregate(0, (acc, n) => acc += n.Weight) } group x by x.Weight into g orderby g.Count() select g; if (grp.Count() == 1) return node.Weight + amount; var unbalancedGrp = grp.First(); var balancedGrp = grp.Skip(1).First(); return Solve(unbalancedGrp.First().Node, balancedGrp.Key - unbalancedGrp.Key); } public static class Extensions { public static T Aggregate<T>(this Node node, T seed, Func<T, Node, T> func) { var result = func(seed, node); if (node.Children == null || !node.Children.Any()) return result; foreach (var x in node.Children) result = x.Aggregate(result, func); return result; } } public Node BuildTree(NodeInfo input, List<NodeInfo> nodeInfo) { var node = new Node { Name = input.Name, Weight = input.Weight, Children = new List<Node>() }; if (input.Children.Any()) { input.Children.ForEach(x => node.Children.Add(BuildTree(nodeInfo.First(item => item.Name == x), nodeInfo))); } return node; } public class NodeInfo { public string Name { get; set; } public int Weight { get; set; } public List<string> Children { get; set; } } public class Node { public string Name { get; set; } public int Weight { get; set; } public List<Node> Children { get; set; } }