Beispiel #1
0
        private int TraverseFindUnbalancedNodeProperWeight(TowerItem towerItem)
        {
            if (towerItem.Children == null)
            {
                return(-1);
            }

            // See if any of our children's towers are unbalanced
            foreach (TowerItem child in towerItem.Children)
            {
                int childResult = TraverseFindUnbalancedNodeProperWeight(child);
                if (childResult != -1)
                {
                    return(childResult);
                }
            }

            // They aren't; so now see if the towers starting from this item are unbalanced
            if (towerItem.Children.Select(childItem => childItem.DescendantsWeight + childItem.Weight).Distinct().Count() > 1)
            {
                return(CalculateWeightCorrection(towerItem));
            }

            return(-1);
        }
Beispiel #2
0
        public void Run()
        {
            List <TowerItem> towerItems = ProcessInput();

            TowerItem rootItem = towerItems.Where(ti => ti.Parent == null).Single();

            Console.WriteLine("Part 1 solution: " + rootItem.Name);

            TraverseAssignDescendantsWeights(rootItem);
            int correctedWeightForIncorrectItem = TraverseFindUnbalancedNodeProperWeight(rootItem);

            Console.WriteLine("Part 2 solution: " + correctedWeightForIncorrectItem);
        }
Beispiel #3
0
        /// <summary>
        /// If there's an existing TowerItem in the list with the specified name, returns it.
        /// Otherwise, creates a new TowerItem with that name, adds it to the list, and returns that.
        /// </summary>
        private TowerItem GetExistingOrNewTowerItem(string name, List <TowerItem> towerItems)
        {
            TowerItem towerItem = towerItems.SingleOrDefault(ti => ti.Name == name);

            if (towerItem == null)
            {
                towerItem = new TowerItem {
                    Name = name, Children = new List <TowerItem>()
                };
                towerItems.Add(towerItem);
            }
            return(towerItem);
        }
Beispiel #4
0
 private void WireUpRelationships(string inputLine, TowerItem towerItem, List <TowerItem> towerItems)
 {
     string[] childNames = GetTowerItemNames(inputLine);
     if (childNames == null)
     {
         return;
     }
     foreach (string childName in childNames)
     {
         TowerItem childItem = GetExistingOrNewTowerItem(childName, towerItems);
         towerItem.Children.Add(childItem);
         childItem.Parent = towerItem;
     }
 }
Beispiel #5
0
        private List <TowerItem> ProcessInput()
        {
            List <TowerItem> towerItems = new List <TowerItem>();

            string[] lines = File.ReadAllLines("day07input.txt");
            foreach (string line in lines)
            {
                string    name      = GetName(line);
                TowerItem towerItem = GetExistingOrNewTowerItem(name, towerItems);
                towerItem.Weight = GetWeight(line);
                WireUpRelationships(line, towerItem, towerItems);
            }

            return(towerItems);
        }
Beispiel #6
0
        private int CalculateWeightCorrection(TowerItem towerItem)
        {
            TowerItem childWithIncorrectWeight = FindChildWithUniqueWeight(towerItem.Children);
            int       correctChildTotalWeight;

            if (towerItem.Children[0] == childWithIncorrectWeight)
            {
                correctChildTotalWeight = towerItem.Children[1].Weight + towerItem.Children[1].DescendantsWeight;
            }
            else
            {
                correctChildTotalWeight = towerItem.Children[0].Weight + towerItem.Children[0].DescendantsWeight;
            }

            int correctedWeightForIncorrectChild = correctChildTotalWeight - childWithIncorrectWeight.DescendantsWeight;

            return(correctedWeightForIncorrectChild);
        }
Beispiel #7
0
        private int TraverseAssignDescendantsWeights(TowerItem towerItem)
        {
            if (towerItem.Children == null)
            {
                towerItem.DescendantsWeight = 0;
                return(towerItem.Weight);
            }

            int totalDescendantsWeights = 0;

            foreach (TowerItem child in towerItem.Children)
            {
                totalDescendantsWeights += TraverseAssignDescendantsWeights(child);
            }

            towerItem.DescendantsWeight = totalDescendantsWeights;
            return(totalDescendantsWeights + towerItem.Weight);
        }
Beispiel #8
0
        private TowerItem FindChildWithUniqueWeight(List <TowerItem> childItems)
        {
            Dictionary <int, int> weightToCountMap = new Dictionary <int, int>();

            for (int i = 0; i < childItems.Count; i++)
            {
                if (!weightToCountMap.ContainsKey(childItems[i].Weight + childItems[i].DescendantsWeight))
                {
                    weightToCountMap[childItems[i].Weight + childItems[i].DescendantsWeight] = 0;
                }
                weightToCountMap[childItems[i].Weight + childItems[i].DescendantsWeight]++;
            }

            int uniqueWeight = weightToCountMap.Single(wtcm => wtcm.Value == 1).Key;

            TowerItem childWithUniqueWeight = childItems.Where(ci => ci.Weight + ci.DescendantsWeight == uniqueWeight).Single();

            return(childWithUniqueWeight);
        }