Permutator::getPermutations()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
ccs 5
cts 5
cp 1
crap 3
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace byrokrat\banking\Rewriter;
6
7
/**
8
 * Generate permutations for a set of values
9
 */
10
class Permutator
11
{
12
    /**
13
     * @param array<mixed> $set
14
     * @return \Generator & iterable<array>
15
     */
16 142
    public static function getPermutations(array $set): \Generator
17
    {
18 142
        foreach (self::getPowerSet($set) as $subset) {
19 142
            foreach (self::generateFixedLengthPermutations($subset) as $perm) {
20 142
                yield $perm;
21
            }
22
        }
23 59
    }
24
25
    /**
26
     * @param array<mixed> $set
27
     * @return array<array>
28
     */
29 142
    private static function getPowerSet(array $set): array
30
    {
31 142
        $results = [[]];
32
33 142
        foreach ($set as $element) {
34 142
            foreach ($results as $combination) {
35 142
                $subset = array_merge([$element], $combination);
36 142
                $results[] = $subset;
37
            }
38
        }
39
40 142
        usort(
41 142
            $results,
42
            function (array $left, array $right): int {
43 142
                return count($left) <=> count($right);
44 142
            }
45
        );
46
47 142
        return array_filter($results);
48
    }
49
50
    /**
51
     * @param array<mixed> $set
52
     * @param array<array> $permutations
53
     * @return \Generator & iterable<array>
54
     */
55 142
    private static function generateFixedLengthPermutations(array $set, array $permutations = []): \Generator
56
    {
57 142
        if (empty($set)) {
58 142
            yield $permutations;
59
        } else {
60 142
            for ($i = count($set)-1; $i>=0; $i--) {
61 142
                $newSet = $set;
62 142
                $newPermutations = $permutations;
63 142
                list($foo) = array_splice($newSet, $i, 1);
64 142
                array_unshift($newPermutations, $foo);
65 142
                yield from self::generateFixedLengthPermutations($newSet, $newPermutations);
66
            }
67
        }
68 142
    }
69
}
70