Exemplo n.º 1
0
        protected override object SolvePart1()
        {
            var nodes = new List <RecursiveCircusNode>();

            foreach (var line in Input)
            {
                var splits = line.Split(new[] { "->" }, StringSplitOptions.None);

                var node = new RecursiveCircusNode
                {
                    Name   = splits[0].Split()[0],
                    Weight = int.Parse(splits[0].Split()[1].Trim().Trim('(', ')'), CultureInfo.InvariantCulture)
                };

                if (splits.Length == 2)
                {
                    node.ChildNodes.AddRange(splits[1].Trim().Split().Select(c => c.Trim(',')).ToList());
                }

                nodes.Add(node);
            }

            var children = nodes.Where(n => n.ChildNodes.Count > 0).SelectMany(n => n.ChildNodes);

            return(nodes.Single(n => !children.Contains(n.Name)).Name);
        }
Exemplo n.º 2
0
        protected override object SolvePart2()
        {
            // Create all nodes.
            var nodes = new List <RecursiveCircusNode>();

            foreach (var line in Input)
            {
                var splits = line.Split(new[] { "->" }, StringSplitOptions.None);

                var node = new RecursiveCircusNode
                {
                    Name   = splits[0].Split()[0],
                    Weight = int.Parse(splits[0].Split()[1].Trim().Trim('(', ')'), CultureInfo.InvariantCulture)
                };

                if (splits.Length == 2)
                {
                    node.ChildNodes.AddRange(splits[1].Trim().Split().Select(c => c.Trim(',')).ToList());
                }

                nodes.Add(node);
            }

            // Build tree
            foreach (var node in nodes)
            {
                foreach (var child in node.ChildNodes)
                {
                    node.Children.Add(nodes.Single(n => n.Name == child));
                }
                node.Children.ForEach(n => n.Parent = node);
            }

            // Get root node (the only one that isn't a child to another node.
            var children = nodes.Where(n => n.ChildNodes.Count > 0).SelectMany(n => n.ChildNodes);
            var rootNode = nodes.Single(n => !children.Contains(n.Name));

            // Traverse tree to find the faulty weight.
            var currentNode = rootNode;
            var lastDiff    = 0;

            while (currentNode != null)
            {
                var childWeights = currentNode.GetChildWeights();

                var diff = childWeights.Distinct().Max() - childWeights.Distinct().Min();

                if (diff == 0)
                {
                    return(currentNode.Weight - lastDiff);
                }

                lastDiff = diff;
                var unique = childWeights.Single(n => childWeights.Count(m => m == n) == 1);
                currentNode = currentNode.Children.Single(n => n.GetTowerWeight() == unique);
            }

            return(null);
        }