Skip to content

Instantly share code, notes, and snippets.

@rvlieshout
Created December 7, 2017 07:21
Show Gist options
  • Save rvlieshout/abb0b609572a1b94dc3831e000029ec5 to your computer and use it in GitHub Desktop.
Save rvlieshout/abb0b609572a1b94dc3831e000029ec5 to your computer and use it in GitHub Desktop.
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