Exemplo n.º 1
0
        /// <summary>
        /// Calculate all possible move permutations given a robots set of cards
        /// </summary>
        /// <param name="robot">Robot</param>
        /// <returns>List of permutations</returns>
        internal static List<List<ProgramCardType>> CalculateMovePermutations(Robot robot)
        {
            var permutations = new List<List<ProgramCardType>>();

            // This is the list of cards that can be placed. Locked registers are not included in this list
            // and should be appended to the end of each list if necessary
            IEnumerable<ProgramCardType> cards = robot.CardsToPlace().Select(ProgramCard.GetCardTypeByPriority);
            var root = new PermutationNode();

            BuildCardPermutationTree(root, cards);

            BuildCardPermutationList(permutations, root);

            return permutations;
        }
        private static int PermutationCounts(Robot robot)
        {
            // BUG: This math does not match our function for calculating permutations. FWIW, I trust the code more than this math.

            // Calculate the number of unique permutations possible with the cards to place.
            // For example, if we need to place the following cards
            // (2) Rotate Left, (1) Rotate Right, (1) Move 1, (1) Move 2 and (2) Move 3
            // Given there are 7 cards to place and the number of cards we need is 5
            // we are calculating P(n,r) where n = 7 and r = 5.
            // Also, given Rotate Left is repeated twice we have x1 = 2 and x2 = 2 for the
            // Move 3 repetitions.
            // Permutations = P(n,r) / (x1!x2!)
            // Permutations = P(7,5) / (2!2!)
            // Permutations = (7! / (7 - 5)!) / (2!2!)
            // Permutations = (5040 / 2) / (4)
            // Permutations = 2520 / 4
            // Permutations = 630

            List<int> cardsToPlace = robot.CardsToPlace().ToList();
            List<ProgramCardType> cardTypesToPlace = cardsToPlace.Select(ProgramCard.GetCardByPriority).ToList();
            int n = cardTypesToPlace.Count();
            int r = Math.Min(n, Constants.RobotRegisters);
            List<Tuple<ProgramCardType, int>> cardDuplicateCounts = Permutations.GetDuplicateItemCounts(cardTypesToPlace).ToList();

            double dividend = (Permutations.Factorial(n) / Permutations.Factorial(n - r));
            double divisor = cardDuplicateCounts.Aggregate<Tuple<ProgramCardType, int>, double>(1, (current, dupe) => current * Permutations.Factorial(dupe.Item2));

            return (int)(dividend / divisor);
        }