Created
December 7, 2017 07:21
-
-
Save rvlieshout/abb0b609572a1b94dc3831e000029ec5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
namespace Day7 | |
{ | |
public class Node | |
{ | |
public string Name { get; set; } | |
public int Weight { get; set; } | |
public Node Parent { get; set; } | |
public string[] ChildNames { get; set; } | |
public List<Node> Children { get; } = new List<Node>(); | |
public int TotalWeight() | |
{ | |
return Weight + Children.Sum(c => c.TotalWeight()); | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var reports = File.ReadLines("input.txt").Select(l => | |
{ | |
var parts = l.Split(' ', 4); | |
return new { name = parts[0], weight = parts[1], supports = parts.Length > 2 ? parts[3].Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries) : null, parts }; | |
}); | |
var nodes = reports.Select(r => new Node { Name = r.name, Weight = int.Parse(r.weight.Substring(1,r.weight.Length-2)), ChildNames = r.supports }).ToList(); | |
nodes.ForEach(n => { | |
n.Parent = nodes.FirstOrDefault(x => x.ChildNames != null && x.ChildNames.Contains(n.Name)); | |
n.Parent?.Children.Add(n); | |
}); | |
nodes.Where(n => n.Parent == null).Select(n => n.Name).ToList().ForEach(Console.WriteLine); | |
foreach (var node in nodes.Where(n => n.Children.Count > 1)) | |
{ | |
var min = node.Children.Min(c => c.TotalWeight()); | |
var max = node.Children.Max(c => c.TotalWeight()); | |
var diff = max - min; | |
if (diff == 0) continue; | |
var countMin = node.Children.Count(c => c.TotalWeight() == min); | |
var countMax = node.Children.Count(c => c.TotalWeight() == max); | |
if (countMax >= countMin) | |
{ | |
var n = node.Children.First(x => x.TotalWeight() == min); | |
var ow = n.Weight; | |
n.Weight += diff; | |
if (IsBalanced(nodes)) | |
{ | |
Console.WriteLine("New node weight: {0}", n.Weight); | |
break; | |
} | |
n.Weight = ow; | |
} | |
else | |
{ | |
var n = node.Children.First(x => x.TotalWeight() == max); | |
var ow = n.Weight; | |
n.Weight -= diff; | |
if (IsBalanced(nodes)) | |
{ | |
Console.WriteLine("New node weight: {0}", n.Weight); | |
break; | |
} | |
n.Weight = ow; | |
} | |
} | |
} | |
static bool IsBalanced(List<Node> nodes) | |
{ | |
foreach (var node in nodes.Where(n => n.Children.Count > 1)) | |
{ | |
var min = node.Children.Min(c => c.TotalWeight()); | |
var max = node.Children.Max(c => c.TotalWeight()); | |
var diff = max - min; | |
if (diff != 0) return false; | |
} | |
return true; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment