public BigInteger GetNumCombos(int numItems = -1, int groupSize = -1) { // This method gets the total number of combos for numItems choose groupSize from Pascal's triangle. // If Pascal's triangle has not been created, then an alternative method is called to get the # of combinations. // If either numItems or groupSize < 0, then NumItems or GroupSize, respectively is used instead. // // Both numItems and groupSize are optional parameters that provide a way to efficiently calculate the number of // combinations from Pascal's Triangle without having to re-create Pascal's Triangle for a different case. But, // both numItems and groupSize must be <= to the original NumItems and GroupSize, respectively, that were used to create the instance. // If either numItems or groupSize < 0, then NumItems or GroupSize, respectively, is used instead. // // Zero is returned if overflow occurred. // The expected runtime of this algorithm is O(1) when Pascal's Triangle is used. // string s; BigInteger numCombos = 0; // numItems = (numItems == -1) ? NumItems : numItems; groupSize = (groupSize == -1) ? GroupSize : groupSize; if ((numItems > NumItems) || (groupSize > GroupSize)) { s = "BinCoeffBigInt:GetNumCombos: numItems > NumItems || groupSize > GroupSize. Neither is allowed. Create a new instance instead."; ApplicationException ae = new ApplicationException(s); throw ae; } if ((numItems == 0) || (groupSize == 0)) { s = "BinCoeffBigInt:GetNumCombos: numItems or groupSize equals zero. Neither is allowed."; ApplicationException ae = new ApplicationException(s); throw ae; } if ((groupSize == 1) || (numItems == groupSize + 1)) { return(numItems); } if (groupSize == numItems) { return(1); } // There are times when Pascal's triangle may not have been legitimately created. For example 5 choose 5. // If this method is called, for example, with 5 choose 3 after being created with a 5 choose 5 case, then this is handled here. if (PasTri == null) { numCombos = Combination.GetNumCombos(numItems, groupSize); return(numCombos); } uint n = (uint)numItems - 1; int startIndex = GroupSize - groupSize; BigInteger[] indexArray = PasTri[startIndex]; int endIndex = indexArray.Length - 1; if (groupSize == 2) { if (numItems != NumItems) { endIndex -= (NumItems - numItems); } numCombos = indexArray[endIndex] + (uint)numItems - 1; } else { if (numItems == NumItems) { BigInteger[] indexArrayPrev = PasTri[startIndex + 1]; int endIndexPrev = indexArrayPrev.Length - 1; numCombos = indexArray[endIndex] + indexArrayPrev[endIndexPrev]; } else { endIndex = endIndex - (NumItems - numItems) + 1; return(indexArray[endIndex]); } } return(numCombos); }