Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
100.00% |
1 / 1 |
|
100.00% |
4 / 4 |
CRAP | |
100.00% |
20 / 20 |
| Combination | |
100.00% |
1 / 1 |
|
100.00% |
4 / 4 |
15 | |
100.00% |
20 / 20 |
| combinationsAll | |
100.00% |
1 / 1 |
3 | |
100.00% |
4 / 4 |
|||
| combinations | |
100.00% |
1 / 1 |
5 | |
100.00% |
9 / 9 |
|||
| combinationsAllCount | |
100.00% |
1 / 1 |
2 | |
100.00% |
1 / 1 |
|||
| combinationsCount | |
100.00% |
1 / 1 |
5 | |
100.00% |
6 / 6 |
|||
| <?php | |
| namespace ia\Math; | |
| use \Generator; | |
| /** | |
| * Combinations of items ['a','b'] => [ ['a'], ['b'], ['a','b'] ] | |
| * | |
| */ | |
| class Combination { | |
| /** | |
| * All combinations of any size, ['a','b'] => [ ['a'], ['b'], ['a','b'] ] | |
| * foreach(Combination:cominationsAll([1,2,3]) as $combinationIndex => $combination) | |
| * | |
| * @param array $set | |
| * @return \Generator each combination as an array [ ['a'], ['b'], ['c'], ['a','b'], ['a','c'], ['b','c'], ['a','b','c'] ] | |
| */ | |
| public static function combinationsAll($set) { | |
| for($size=1, $limit = count($set); $size <= $limit; ++$size) { | |
| foreach(self::combinations($set, $size) as $c) { | |
| yield $c; | |
| } | |
| } | |
| } | |
| /** | |
| * All combinations, no duplicates, of size $size in $set as a Generator. | |
| * foreach( combinations(['a','b','c'], 2) as $combinationIndex => $combination) => each $c is [a,b],[ a,c] and [b,c] | |
| * | |
| * @param array $set | |
| * @param int $size | |
| * @return \Generator | |
| */ | |
| public static function combinations($set = [], $size = 0) { | |
| if($size === 0) { | |
| yield []; | |
| } elseif(count($set) > 0) { | |
| $prefix = [array_shift($set)]; | |
| foreach(self::combinations($set, $size-1) as $suffix) { | |
| yield array_merge($prefix, $suffix); | |
| } | |
| foreach(self::combinations($set, $size) as $next) { | |
| yield $next; | |
| } | |
| } | |
| } | |
| /** | |
| * Number of all combinations for $setLength elements | |
| * | |
| * @param int $setLength | |
| * @return int | |
| */ | |
| public static function combinationsAllCount(int $setLength) { | |
| return $setLength > 0 ? 2 ** $setLength - 1 : 0; | |
| } | |
| /** | |
| * Number of combinations of $setLength items grouped in $itemsNumber. considers a,b equal to b,a | |
| * | |
| * @param int $setLength | |
| * @param int $itemsNumber | |
| * @return int | |
| */ | |
| public static function combinationsCount(int $setLength, int $itemsNumber) { | |
| if($itemsNumber > $setLength || $itemsNumber <= 0 || $setLength <= 0) { | |
| return 0; | |
| } | |
| $number = $setLength; | |
| for($j = 2, $i = $setLength-1, $limit = $setLength - $itemsNumber + 1; $i >= $limit; --$i, ++$j) { | |
| $number *= $i/$j; | |
| } | |
| return floor($number); | |
| } | |
| } |