private void Test13Choose5() { // This function tests out the binomial coefficien class for the 13 choose 5 case. int n = 13; int k = 5; ulong numCombos = BinCoeffBase.GetCombosCount(n, k); if (numCombos != 1287) { DisplayMsg("BinCoeffBase.GetNumCombos did not calculate the correct value for 13 choose 5 case."); return; } // Create the BinCoeff object that will be used for all the tests for the 13 choose 5 case. // The table is created when the 3rd argument of the constuctor is set to true. BC = new BinCoeff <uint>(n, k, 0, true); try { TestTableData(); VerifyPascalsTriangle(); VerifyTranslastion(); TestOutputIndexes(); } catch (Exception e) { DisplayMsg($"The Test 13 choose 5 tests did not complete successfully - {e.Message}."); return; } DisplayMsg("Test13Choose5: completed successfully."); }
private bool TestRankComboulong(int numItems, int groupSize) { // This method tests getting the rank and combination for the specified case. // If the test failed, then false is returned. Otherwise true is returned. string s; bool overflow; int n = numItems, k = groupSize; // Create the bin coeff object required to get all the combos for this n choose k combination. BinCoeffL bcl = new BinCoeffL(n, k); // The Kindexes array specifies the indexes for a combination. int[] kIndexes = new int[k]; ulong numCombos = bcl.TotalCombos, rankLoop; bcl.GetCombFromRank(numCombos - 1, kIndexes); uint numCombos2 = (uint)BinCoeffBase.GetRankAlt(kIndexes, n, k, out overflow) + 1; if (numCombos != numCombos2) { s = $"TestRankComboLong: {n} choose {k}: # of combos not the same with alternate method - {numCombos} .vs. {numCombos2}"; Console.WriteLine(s); return(false); } ulong rank, offset = 1; // Loop thru all the combinations for this n choose k case if # of combos <= 1000000. // Otherwise, choose a random rank between 100 & 200. if (numCombos > 1000000) { Random rand = new Random(-12345); offset = (ulong)rand.Next(100, 200); } for (rankLoop = 0; rankLoop < numCombos; rankLoop += offset) { // Get the k-indexes for this combination. bcl.GetCombFromRank(rankLoop, kIndexes); // Verify that the Kindexes returned can be used to retrieve the rank of the combination. rank = bcl.GetRank(true, kIndexes, out overflow, groupSize); if (rank != rankLoop) { s = $"TestRankComboLong: {n} choose {k}: GetRank or GetCombFromRank failed - value of {rank} != rank at {rankLoop}"; Console.WriteLine(s); return(false); } } s = $"TestRankComboLong: {n} choose {k} completed successfully."; Console.WriteLine(s); return(true); }
private void Test100Choose95SubCases() { // This method tests out the new int functionality of specifying a lower n choose k case without having to // create a new version of Pascal's Triangle to handle it. This version checks the 100 choose 95 case. // string s; bool overflow; int n = 100, k = 95, kLoop; BinCoeffL bcl = new BinCoeffL(n, k); ulong numCombos, numCombos2, rank, highRank; uint rankLoop; int[] kIndexes = new int[k]; // Test all subcases of 100 choose 95. for (kLoop = k; kLoop > 0; kLoop--) { numCombos = bcl.GetNumCombos(n, kLoop); numCombos2 = BinCoeffBase.GetCombosCount(n, kLoop); if (numCombos != numCombos2) { s = $"Test100Choose95SubCases: Error - {n} choose {k}: # of combos does not match."; Console.WriteLine(s); return; } // Test the lowest 10 ranks and the highest 10 ranks for each subcase test case. for (rankLoop = 1; rankLoop <= 10; rankLoop++) { bcl.GetCombFromRank(rankLoop, kIndexes, n, kLoop); rank = bcl.GetRank(true, kIndexes, out overflow, kLoop); if (rank != rankLoop) { s = $"Test100Choose95SubCases: Error - {n} choose {kLoop}: rank or combo is wrong."; Console.WriteLine(s); return; } highRank = numCombos - rankLoop; bcl.GetCombFromRank(highRank, kIndexes, n, kLoop); rank = bcl.GetRank(true, kIndexes, out overflow, kLoop); if (rank != highRank) { s = $"Test100Choose95SubCases: Error - {n} choose {kLoop}: high rank or combo is wrong."; Console.WriteLine(s); return; } } } }
private void TestOutputIndexes() { // This test function writes out each unique combination of the binomial coefficient values out to a file. // 2 tests are done here. The first test outputs the underlying reprensentation of the data, // which in this case is simply each of the 1287 5 card no-pair poker hands, including straights. // The 2nd test writes out the numeric value of the K indexes for each combination. // string[] dispChars = new string[] { "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A" }; string[] dispChars2 = null; string dataPath = Application.StartupPath; int n = dataPath.LastIndexOf("bin\\"); if (n >= 0) { dataPath = dataPath.Substring(0, n); } // The first test writes out the values given in the string DispChars instead of numeric values. string fileName = dataPath + "TestResults13Choose5 Disp Hands.txt"; BinCoeffBase.OutputCombos(fileName, dispChars, "", " ", 60, BC, 0, 1286); // The 2nd test writes out the numeric values for each combination. fileName = dataPath + "TestResults13Choose5 Disp Values.txt"; BinCoeffBase.OutputCombos(fileName, dispChars2, " ", ", ", 60, BC, 1286, 0); }
private void Test35Choose16() { // This function tests out the long binomial coefficien class for the case 35 choose 16. // This produces one of the largest number of combinations that will fit within a uint: // 4,059,928,950 // int n = 35; int k = 16; string s; bool overflow; // Create the BinCoeff object that will be used for all the tests for the 50 choose 25 case. var bc = new BinCoeff <uint>(n, k); if (bc.TotalCombos != 4059928950) { s = $"Test35Choose16: Error calculating # of combos - {BC.TotalCombos}."; DisplayMsg(s); throw new ApplicationException(s); } int kLoop; uint rank = 0, numCombos, numCombos2, highRank, rank2, rankLoop; int[] kIndexes = new int[k]; // Try getting the first and last 5 combinations and ranks for this case. try { // Test all subcases of 35 choose 16. for (kLoop = k; kLoop > 0; kLoop--) { numCombos = bc.GetNumCombos(n, kLoop); numCombos2 = (uint)BinCoeffBase.GetCombosCount(n, kLoop); if (numCombos != numCombos2) { s = $"Test100Choose95SubCases: Error - {n} choose {k}: # of combos does not match."; Console.WriteLine(s); return; } // Test the lowest 10 ranks and the highest 10 ranks for each subcase test case. for (rankLoop = 1; rankLoop < 10; rankLoop++) { bc.GetCombFromRank(rankLoop, kIndexes, n, kLoop); rank = bc.GetRank(true, kIndexes, out overflow, kLoop); if (rank != kLoop) { s = $"Test67Choose33: Either rank or combos was not calculated correctly. rank = {rank}, kloop = {kloop}"; DisplayMsg(s); throw new ApplicationException(s); } highRank = numCombos - rankLoop; rank2 = bc.GetRank(true, kIndexes, out overflow); bc.GetCombFromRank(highRank, kIndexes, n, kLoop); rank2 = bc.GetRank(true, kIndexes, out overflow); if (highRank != rank2) { s = $"Test67Choose33: Either rank or combos was not calculated correctly. highRank = {highRank}, rank2 = {rank2}"; DisplayMsg(s); throw new ApplicationException(s); } highRank--; } } } catch (Exception e) { DisplayMsg($"Test67Choose33: Exception = {e.Message}."); return; } DisplayMsg("Test67Choose33: completed successfully."); }
private TestResult TestLongSubCases(int n, int k) { // This method tests out the new int functionality of specifying a lower n choose k case without having to // create a new version of Pascal's Triangle to handle it. n & k specifies the main n choose k case. // string s; int nLoop, kLoop; BinCoeffL bcl = new BinCoeffL(n, k); ulong numCombos, numCombos2, rank, rankHigh, rank2, rankLoop; int[] kIndexes = new int[k]; // If the # of combos overflowed, then don't try this case with uint. if (bcl.TotalCombos == 0) { return(TestResult.IntOverflow); } // Try getting the rank and combination for all subcases of n choose k. for (kLoop = k; kLoop > 0; kLoop--) { for (nLoop = n; nLoop >= kLoop; nLoop--) { numCombos = bcl.GetNumCombos(nLoop, kLoop); numCombos2 = (uint)BinCoeffBase.GetCombosCount(nLoop, kLoop); if (numCombos != numCombos2) { s = $"TestIntSubCases: Error - {n} choose {k}: # of combos does not match."; Console.WriteLine(s); return(TestResult.Failed); } ulong comboCount = numCombos; // Loop thru all the combinations for this n choose k case if # of combos <= 1000. // Otherwise, just do the lowest ranked 500 and the highest ranked 500. if (numCombos > 1000) { comboCount = 500; } // Loop thru the combinations for this n choose k case. for (rankLoop = 0; rankLoop < comboCount; rankLoop++) { bcl.GetCombFromRank(rankLoop, kIndexes, nLoop, kLoop); rank = bcl.GetRank(true, kIndexes, out bool overflow, kLoop); if (rank != rankLoop) { s = $"TestIntSubCases: Error - {n} choose {k}: rank or combo is wrong."; Console.WriteLine(s); return(TestResult.Failed); } // If not doing all the combinations, then process the high ranks. if (numCombos > comboCount) { rankHigh = numCombos - rankLoop - 1; // Get the k-indexes for this combination. bcl.GetCombFromRank(rankHigh, kIndexes, nLoop, kLoop); // Verify that the Kindexes returned can be used to retrieve the rank of the combination. rank2 = bcl.GetRank(true, kIndexes, out overflow, kLoop); if (rank2 != rankHigh) { s = $"TestIntSubCases: Error - {n} choose {k}: GetRank or GetCombFromRank failed - {rank2} != rankHigh at {rankLoop}"; Console.WriteLine(s); return(TestResult.Failed); } } } } } return(TestResult.Passed); }
private bool TestRankCombo(int numItems, int groupSize) { // This method tests getting the rank and combination for the specified 32-bit int case. // If the test failed, then false is returned. Otherwise true is returned. string s; int n = numItems, k = groupSize; bool overflow; // Create the bin coeff object required to get all the combos for this n choose k combination. BinCoeff <int> bc = new BinCoeff <int>(n, k); // The Kindexes array specifies the indexes for a combination. int[] kIndexes = new int[k]; uint numCombos = bc.TotalCombos, rankLoop; bc.GetCombFromRank(numCombos - 1, kIndexes); uint numCombos2 = (uint)BinCoeffBase.GetRankAlt(kIndexes, n, k, out overflow) + 1; if (overflow) { s = $"TestRankCombo: {n} choose {k}: # of combos overflowed with alt method."; Console.WriteLine(s); return(false); } if (numCombos != numCombos2) { s = $"TestRankCombo: {n} choose {k}: # of combos not the same with alternate method - {numCombos} .vs. {numCombos2}"; Console.WriteLine(s); return(false); } uint rank2, rankHigh; uint comboCount = numCombos; // Loop thru all the combinations for this n choose k case if # of combos <= 1000. // Otherwise, just do the lowest ranked 500 and the highest ranked 500. if (numCombos > 1000) { comboCount = 500; } // Loop thru all the combinations for this n choose k case. for (rankLoop = 1; rankLoop < comboCount; rankLoop++) { // Get the k-indexes for this combination. bc.GetCombFromRank(rankLoop, kIndexes); // Verify that the Kindexes returned can be used to retrieve the rank of the combination. rank2 = bc.GetRank(true, kIndexes, out overflow); if (rank2 != rankLoop) { s = $"TestRankCombo: {n} choose {k}: GetRank or GetCombFromRank failed - value of {rank2} != rank at {rankLoop}"; Console.WriteLine(s); return(false); } // If not doing all the combinations, then process the high ranks. if (numCombos > comboCount) { rankHigh = numCombos - rankLoop - 1; // Get the k-indexes for this combination. bc.GetCombFromRank(rankHigh, kIndexes); // Verify that the Kindexes returned can be used to retrieve the rank of the combination. rank2 = bc.GetRank(true, kIndexes, out overflow); if (rank2 != rankHigh) { s = $"TestRankCombo: {n} choose {k}: GetRank or GetCombFromRank failed - value of {rank2} != rankHigh at {rankLoop}"; Console.WriteLine(s); return(false); } } } s = $"TestRankCombo: {n} choose {k} completed successfully."; Console.WriteLine(s); return(true); }