I\'m doing a code that eliminates unneeded combinations such as I (ABCDE) do not want AAA BBB AB BA only want ABC ABD ABE .... so on, want it to be valid for any situation,
require_once 'Math/Combinatorics.php';
$combinatorics = new Math_Combinatorics;
$set = range(1,6);
$combosWithoutRepetition = $combinatorics->combinations($set, 3);
foreach ($combosWithoutRepetition as $combo) {
echo join(',', $combo), "\n";
}
http://pear.php.net/package/Math_Combinatorics
you don't need to install pear, you can just download that package and use it.
Original code: https://stackoverflow.com/a/2617080/661872 I just added $len
part.
<?php
// function to generate and print all N! permutations of $str. (N = strlen($str)).
function permute($str,$i,$n,$len) {
global $ret;
if ($i == $n){
if(in_array(substr($str,0,$len),$ret)==false){$ret[]=substr($str,0,$len);}
}else {
for ($j = $i; $j < $n; $j++) {
swap($str,$i,$j);
permute($str, $i+1, $n, $len);
swap($str,$i,$j); // backtrack.
}
}
}
// function to swap the char at pos $i and $j of $str.
function swap(&$str,$i,$j) {
$temp = $str[$i];
$str[$i] = $str[$j];
$str[$j] = $temp;
}
$ret = array();
$str = "123456";
permute($str,0,strlen($str), 3); // call the function.
print_r($ret);
/**
* Array
(
[0] => 123
[1] => 124
[2] => 125
[3] => 126
[4] => 132
[5] => 134
[6] => 135
[7] => 136
[8] => 143
[9] => 142
[10] => 145
[11] => 146
[12] => 153
[13] => 154
[14] => 152
[15] => 156
[16] => 163
[17] => 164
[18] => 165
[19] => 162
[20] => 213
[21] => 214
[22] => 215
[23] => 216
[24] => 231
[25] => 234
[26] => 235
[27] => 236
[28] => 243
[29] => 241
[30] => 245
[31] => 246
[32] => 253
[33] => 254
[34] => 251
[35] => 256
[36] => 263
[37] => 264
[38] => 265
[39] => 261
[40] => 321
[41] => 324
[42] => 325
[43] => 326
[44] => 312
[45] => 314
[46] => 315
[47] => 316
[48] => 341
[49] => 342
[50] => 345
[51] => 346
[52] => 351
[53] => 354
[54] => 352
[55] => 356
[56] => 361
[57] => 364
[58] => 365
[59] => 362
[60] => 423
[61] => 421
[62] => 425
[63] => 426
[64] => 432
[65] => 431
[66] => 435
[67] => 436
[68] => 413
[69] => 412
[70] => 415
[71] => 416
[72] => 453
[73] => 451
[74] => 452
[75] => 456
[76] => 463
[77] => 461
[78] => 465
[79] => 462
[80] => 523
[81] => 524
[82] => 521
[83] => 526
[84] => 532
[85] => 534
[86] => 531
[87] => 536
[88] => 543
[89] => 542
[90] => 541
[91] => 546
[92] => 513
[93] => 514
[94] => 512
[95] => 516
[96] => 563
[97] => 564
[98] => 561
[99] => 562
[100] => 623
[101] => 624
[102] => 625
[103] => 621
[104] => 632
[105] => 634
[106] => 635
[107] => 631
[108] => 643
[109] => 642
[110] => 645
[111] => 641
[112] => 653
[113] => 654
[114] => 652
[115] => 651
[116] => 613
[117] => 614
[118] => 615
[119] => 612
)
*/
?>
I have written a class to handle common functions for working with the binomial coefficient, which is the type of problem that your problem falls under. It performs the following tasks:
Outputs all the K-indexes in a nice format for any N choose K to a file. The K-indexes can be substituted with more descriptive strings or letters. This method makes solving this type of problem quite trivial.
Converts the K-indexes to the proper index of an entry in the sorted binomial coefficient table. This technique is much faster than older published techniques that rely on iteration. It does this by using a mathematical property inherent in Pascal's Triangle. My paper talks about this. I believe I am the first to discover and publish this technique, but I could be wrong.
Converts the index in a sorted binomial coefficient table to the corresponding K-indexes. I believe it might be faster than the link you have found.
Uses Mark Dominus method to calculate the binomial coefficient, which is much less likely to overflow and works with larger numbers.
The class is written in .NET C# and provides a way to manage the objects related to the problem (if any) by using a generic list. The constructor of this class takes a bool value called InitTable that when true will create a generic list to hold the objects to be managed. If this value is false, then it will not create the table. The table does not need to be created in order to perform the 4 above methods. Accessor methods are provided to access the table.
There is an associated test class which shows how to use the class and its methods. It has been extensively tested with 2 cases and there are no known bugs.
To read about this class and download the code, see Tablizing The Binomial Coeffieicent.
It should not be hard to convert this class to Perl. Another option might be to convert it to Java and then call it from Perl.
From your example above, it looks like you are using the case of 6 choose 3, which means that there are 6 possible items to be taken 3 at a time. So, some example code for doing this would look something like the following:
// Create the binomial coefficient object for the 6 choose 3 case and
// do not bother to create the list of objects table.
BinCoeff<int> BC = new BinCoeff<int>(6, 3, false);
int[] KIndexes = new int[3];
int NumCombos6Choose3 = BinCoeff<int>.GetBinCoeff(6, 3);
// Loop through all of the combinations for this case.
for (int Loop = 0; Loop < NumCombos6Choose3; Loop++)
{
// Get the K-Indexes for this combination.
// The combinations are returned in rank order.
BC.GetKIndexes(Loop, KIndexes);
// Print out the K-Indexes or any other processing.
...
}