Ejemplo n.º 1
0
    /// <summary>
    /// Finds the weight that the program that unbalances the structure should be to balance it, if found.
    /// </summary>
    /// <param name="root">The root node of the structure.</param>
    /// <returns>
    /// The weight the program that unbalances the tower described by <paramref name="root"/> should be, if any; otherwise zero.
    /// </returns>
    private static int FindDesiredWeightOfUnbalancedDisc(ProgramDisc root)
    {
        if (root.ProgramsHeld.Length == 0)
        {
            // Leaf node, no children to inspect
            return(0);
        }

        var unbalancedSubtree = root.Children
                                .GroupBy((p) => FindDesiredWeightOfUnbalancedDisc(p))
                                .Where((p) => p.Key is not 0)
                                .SingleOrDefault();

        if (unbalancedSubtree != null)
        {
            // The unbalanced program was found in the subtree
            return(unbalancedSubtree.Key);
        }

        var         childWeights = root.Children.GroupBy((p) => p.TotalWeight);
        ProgramDisc?unbalanced   = childWeights.FirstOrDefault((p) => p.ExactCount(1))?.FirstOrDefault();

        if (unbalanced is null)
        {
            // All children's trees weigh the same
            return(0);
        }

        int currentWeight = unbalanced.TotalWeight;
        int targetWeight  = childWeights.First((p) => !p.ExactCount(1)).Key;

        int delta = currentWeight - targetWeight;

        return(unbalanced.Weight - delta);
    }
Ejemplo n.º 2
0
    /// <summary>
    /// Finds the weight that the program that unbalances the structure should be to balance it.
    /// </summary>
    /// <param name="structure">A collection of strings representing the structure of the tower.</param>
    /// <returns>
    /// The weight the program that unbalances the tower described by <paramref name="structure"/> should be.
    /// </returns>
    public static int FindDesiredWeightOfUnbalancedDisc(IEnumerable <string> structure)
    {
        var    tower      = BuildStructure(structure);
        string bottomName = FindBottomProgramName(tower.Values);

        ProgramDisc bottom = tower[bottomName];

        return(FindDesiredWeightOfUnbalancedDisc(bottom));
    }
Ejemplo n.º 3
0
    /// <summary>
    /// Builds the structure of discs.
    /// </summary>
    /// <param name="structure">A collection of strings representing the structure of the tower.</param>
    /// <returns>
    /// An <see cref="IDictionary{TKey, TValue}"/> containing the programs with references to their parent and children, keyed by their names.
    /// </returns>
    private static Dictionary <string, ProgramDisc> BuildStructure(IEnumerable <string> structure)
    {
        var programs = structure
                       .Select((p) => new ProgramDisc(p))
                       .ToDictionary((p) => p.Name, (p) => p);

        foreach (ProgramDisc program in programs.Values)
        {
            foreach (string name in program.ProgramsHeld)
            {
                ProgramDisc child = programs[name];

                child.Parent = program;
                program.Children.Add(child);
            }
        }

        return(programs);
    }