From 31b6b602714cad49771b5bd11c4a39b23732b02c Mon Sep 17 00:00:00 2001 From: Pol Dellaiera Date: Wed, 29 Mar 2017 14:32:28 +0200 Subject: [PATCH] Update the Combinations generator based on Mark Wilson's array-subsets repository. --- src/Generators/Combinations.php | 76 +++++++++++++++++++++++ tests/src/Generators/CombinationsTest.php | 74 ++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 src/Generators/Combinations.php create mode 100644 tests/src/Generators/CombinationsTest.php diff --git a/src/Generators/Combinations.php b/src/Generators/Combinations.php new file mode 100644 index 0000000..3b50983 --- /dev/null +++ b/src/Generators/Combinations.php @@ -0,0 +1,76 @@ + + */ +class Combinations extends Combinatorics { + + /** + * Alias of the get() method. + * + * @return \Generator + * The prime generator. + */ + public function generator() { + return $this->get($this->getDataset(), $this->getLength()); + } + + /** + * The generator. + * + * @param array $dataset + * The dataset. + * + * @codingStandardsIgnoreStart + * @return \Generator + * @codingStandardsIgnoreEnd + */ + protected function get(array $dataset, $length) { + $originalLength = count($dataset); + $remainingLength = $originalLength - $length + 1; + for ($i = 0; $i < $remainingLength; $i++) { + $current = $dataset[$i]; + if ($length === 1) { + yield [$current]; + } else { + $remaining = array_slice($dataset, $i + 1); + foreach ($this->get($remaining, $length - 1) as $permutation) { + array_unshift($permutation, $current); + yield $permutation; + } + } + } + } + + /** + * {@inheritdoc} + */ + public function count() { + return $this->fact(count($this->getDataset())) / ($this->fact($this->getLength()) * $this->fact(count($this->getDataset()) - $this->getLength())); + } + + /** + * Convert the iterator into an array. + * + * @return array + * The elements. + */ + public function toArray() { + $data = array(); + + foreach ($this->generator() as $value) { + $data[] = $value; + } + + return $data; + } + +} diff --git a/tests/src/Generators/CombinationsTest.php b/tests/src/Generators/CombinationsTest.php new file mode 100644 index 0000000..9cc8869 --- /dev/null +++ b/tests/src/Generators/CombinationsTest.php @@ -0,0 +1,74 @@ +assertEquals($input['dataset'], $combinations->getDataset()); + $this->assertEquals($input['length'], $combinations->getLength()); + $this->assertEquals($expected['dataset'], $combinations->toArray(), "\$canonicalize = true", $delta = 0.0, $maxDepth = 10, $canonicalize = TRUE); + $this->assertEquals($expected['count'], $combinations->count()); + } + + /** + * The data provider. + * + * @return array + * The test input values and their expected output. + */ + public function simpleValueProvider() { + return [ + [ + 'input' => [ + 'dataset' => [1, 2, 3, 4, 5], + 'length' => 5, + ], + 'output' => [ + 'dataset' => [ + [1, 2, 3, 4, 5], + ], + 'count' => 1, + ], + ], + [ + 'input' => [ + 'dataset' => [1, 2, 3, 4, 5], + 'length' => 3, + ], + 'output' => [ + 'dataset' => [ + [1, 2, 3], + [1, 2, 4], + [1, 2, 5], + [1, 3, 4], + [1, 3, 5], + [1, 4, 5], + [2, 3, 4], + [2, 3, 5], + [2, 4, 5], + [3, 4, 5], + ], + 'count' => 10, + ], + ], + ]; + } + +}