Completed
Push — master ( ee6b13...b11566 )
by Pol
04:05
created

Permutations   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Coupling/Cohesion

Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 16
cbo 2
dl 0
loc 122
ccs 44
cts 44
cp 1
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A count() 0 3 1
B generator() 0 22 5
B permute() 0 26 6
A swap() 0 5 1
A toArray() 0 9 2
1
<?php
2
3
namespace drupol\phpermutations;
4
5
use drupol\phpermutations\Iterators\Combinations;
6
7
/**
8
 * Class Permutations.
9
 *
10
 * @package drupol\phpermutations
11
 */
12
class Permutations extends Combinatorics {
13
14
  /**
15
   * Permutations constructor.
16
   *
17
   * @param array $dataset
18
   *   The dataset.
19
   * @param int $length
0 ignored issues
show
Documentation introduced by
Should the type for parameter $length not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
20
   *   The length of the requested permutations.
21
   */
22 4
  public function __construct(array $dataset = array(), $length = NULL) {
23 4
    parent::__construct($dataset, $length);
24 4
  }
25
26
  /**
27
   * Count the number of permutations.
28
   *
29
   * @return int
30
   *   The number of element.
31
   */
32 4
  public function count() {
33 4
    return $this->fact(count($this->getDataset())) / $this->fact(count($this->getDataset()) - $this->getLength());
34
  }
35
36
  /**
37
   * Return the permutations.
38
   *
39
   * @return array
40
   *   The permutations result set.
41
   */
42 3
  public function generator() {
43 3
    $combinations = new Combinations($this->getDataset(), $this->getLength());
44 3
    $result = array();
45
46 3
    foreach ($combinations->toArray() as $subset) {
47 3
      $set = $subset;
48 3
      $perms = array();
49 3
      $size = count($subset) - 1;
50 3
      $perm = range(0, $size);
51 3
      $j = 0;
52
53
      do {
54 3
        foreach ($perm as $i) {
55 3
          $perms[$j][] = $set[$i];
56 3
        }
57 3
      } while ($perm = $this->permute($perm, $size) and ++$j);
58
59 3
      $result = array_merge($result, $perms);
60 3
    }
61
62 3
    return $result;
63
  }
64
65
  /**
66
   * Internal method to compute the permutations.
67
   *
68
   * @param array $items
69
   *   The items.
70
   * @param int $length
71
   *   The length.
72
   *
73
   * @return bool|array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use false|array.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
74
   *   The permutations.
75
   */
76 3
  protected function permute(array $items, $length) {
77
    // Slide down the array looking for where we're smaller than the next guy.
78 3
    for ($i = $length - 1; $i >= 0 && $items[$i] >= $items[$i + 1]; --$i) {
79 3
    }
80
81
    // If this doesn't occur, we've finished our permutations
82
    // the array is reversed: (1, 2, 3, 4) => (4, 3, 2, 1)
83 3
    if ($i == -1) {
84 3
      return FALSE;
85
    }
86
87
    // Slide down the array looking for a bigger number
88
    // than what we found before.
89 3
    for ($j = $length; $items[$j] <= $items[$i]; --$j) {
90 3
    }
91
92
    // Swap them.
93 3
    $this->swap($items[$i], $items[$j]);
94
95
    // Now reverse the elements in between by swapping the ends.
96 3
    for (++$i, $j = $length; $i < $j; ++$i, --$j) {
97 3
      $this->swap($items[$i], $items[$j]);
98 3
    }
99
100 3
    return $items;
101
  }
102
103
  /**
104
   * Swap two variables.
105
   *
106
   * @param mixed $x
107
   *   The first variable.
108
   * @param mixed $y
109
   *   The second variable.
110
   */
111 3
  protected function swap(&$x, &$y) {
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $x. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
Comprehensibility introduced by
Avoid variables with short names like $y. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
112 3
    $tmp = $x;
113 3
    $x = $y;
114 3
    $y = $tmp;
115 3
  }
116
117
  /**
118
   * Transform the iterator into an array.
119
   *
120
   * @return array
121
   *   The permutations result set.
122
   */
123 4
  public function toArray() {
124 4
    $results = array();
125
126 4
    foreach ($this->generator() as $value) {
127 4
      $results[] = $value;
128 4
    }
129
130 4
    return $results;
131
  }
132
133
}
134