1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace drupol\phpermutations\Iterators; |
4
|
|
|
|
5
|
|
|
use drupol\phpermutations\Combinatorics; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Class Prime. |
9
|
|
|
* |
10
|
|
|
* @package drupol\phpermutations\Iterators |
11
|
|
|
*/ |
12
|
|
|
class Prime extends Combinatorics implements \Iterator, \Countable |
13
|
|
|
{ |
14
|
|
|
/** |
15
|
|
|
* The minimum limit. |
16
|
|
|
* |
17
|
|
|
* @var int |
18
|
|
|
*/ |
19
|
|
|
protected $min; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* The maximum limit. |
23
|
|
|
* |
24
|
|
|
* @var int |
25
|
|
|
*/ |
26
|
|
|
protected $max; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* The key. |
30
|
|
|
* |
31
|
|
|
* @var int |
32
|
|
|
*/ |
33
|
|
|
protected $key; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Prime constructor. |
37
|
|
|
*/ |
38
|
|
|
public function __construct() |
39
|
|
|
{ |
40
|
|
|
$this->setMaxLimit(PHP_INT_MAX); |
41
|
|
|
$this->setMinLimit(0); |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* {@inheritdoc} |
46
|
|
|
*/ |
47
|
|
View Code Duplication |
public function current() |
|
|
|
|
48
|
|
|
{ |
49
|
|
|
for ($i = $this->key(); $i < $this->getMaxLimit(); $i++) { |
50
|
|
|
if ($this->isPrimeNumber($i)) { |
51
|
|
|
$this->key = $i; |
52
|
|
|
|
53
|
|
|
return $i; |
54
|
|
|
} |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
return $this->getMaxLimit(); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* {@inheritdoc} |
62
|
|
|
*/ |
63
|
|
|
public function next() |
64
|
|
|
{ |
65
|
|
|
$this->key++; |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* {@inheritdoc} |
70
|
|
|
*/ |
71
|
|
|
public function key() |
72
|
|
|
{ |
73
|
|
|
return $this->key; |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* {@inheritdoc} |
78
|
|
|
*/ |
79
|
|
|
public function valid() |
80
|
|
|
{ |
81
|
|
|
return $this->current() < $this->getMaxLimit(); |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* {@inheritdoc} |
86
|
|
|
*/ |
87
|
|
|
public function rewind() |
88
|
|
|
{ |
89
|
|
|
$this->key = $this->getMinLimit(); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* Count elements of an object. |
94
|
|
|
* |
95
|
|
|
* @return int |
96
|
|
|
* The number of element. |
97
|
|
|
*/ |
98
|
|
|
public function count() |
99
|
|
|
{ |
100
|
|
|
return count($this->toArray()); |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* Convert the iterator into an array. |
105
|
|
|
* |
106
|
|
|
* @return array |
107
|
|
|
* The elements. |
108
|
|
|
*/ |
109
|
|
|
public function toArray() |
110
|
|
|
{ |
111
|
|
|
$data = []; |
112
|
|
|
|
113
|
|
|
for ($this->rewind(); $this->valid(); $this->next()) { |
114
|
|
|
$data[] = $this->current(); |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
return $data; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* Set the maximum limit. |
122
|
|
|
* |
123
|
|
|
* @param int $max |
124
|
|
|
* The limit. |
125
|
|
|
*/ |
126
|
|
|
public function setMaxLimit($max) |
127
|
|
|
{ |
128
|
|
|
$this->max = $max; |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Get the maximum limit. |
133
|
|
|
* |
134
|
|
|
* @return int |
135
|
|
|
* The limit. |
136
|
|
|
*/ |
137
|
|
|
public function getMaxLimit() |
138
|
|
|
{ |
139
|
|
|
return intval($this->max); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* Set the minimum limit. |
144
|
|
|
* |
145
|
|
|
* @param int $min |
146
|
|
|
* The limit. |
147
|
|
|
*/ |
148
|
|
|
public function setMinLimit($min) |
149
|
|
|
{ |
150
|
|
|
$this->min = $min; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* Get the minimum limit. |
155
|
|
|
* |
156
|
|
|
* @return int |
157
|
|
|
* The limit. |
158
|
|
|
*/ |
159
|
|
|
public function getMinLimit() |
160
|
|
|
{ |
161
|
|
|
return $this->min <= 2 ? 2 : intval($this->min); |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
/** |
165
|
|
|
* Test if a number is prime or not. |
166
|
|
|
* |
167
|
|
|
* @param int $number |
168
|
|
|
* The number to test. |
169
|
|
|
* |
170
|
|
|
* @return bool |
171
|
|
|
* The true if the number is prime, false otherwise. |
172
|
|
|
*/ |
173
|
|
|
protected function isPrimeNumber($number) |
174
|
|
|
{ |
175
|
|
|
$number = abs($number); |
176
|
|
|
|
177
|
|
|
// 2 is an exception. |
178
|
|
|
if (2 === $number) { |
179
|
|
|
return true; |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
// Check if number is even. |
183
|
|
|
if (!($number & 1)) { |
184
|
|
|
return false; |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
$sqrtNumber = sqrt($number); |
188
|
|
|
for ($divisor = 3; $divisor <= $sqrtNumber; $divisor += 2) { |
189
|
|
|
if ($number % $divisor === 0) { |
190
|
|
|
return false; |
191
|
|
|
} |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
return true; |
195
|
|
|
} |
196
|
|
|
} |
197
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.