Passed
Push — master ( a2fa16...8a4497 )
by Pol
11:27
created

FiniteGroup::valid()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 1
cts 1
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace drupol\phpermutations\Iterators;
6
7
use drupol\phpermutations\Iterators;
8
9
use function count;
10
11
/**
12
 * Class FiniteGroup.
13
 *
14
 * The finite group is an abelian finite cyclic group.
15
 */
16
class FiniteGroup extends Iterators
17
{
18
    /**
19
     * The group.
20
     *
21
     * @var int[]
22
     */
23
    protected $group;
24
25
    /**
26
     * The group size.
27
     *
28
     * @var int
29
     */
30
    protected $size;
31
32
    /**
33
     * Count elements of an object.
34
     *
35
     * @return int
36
     *             The number of element
37
     */
38
    public function count()
39 2
    {
40
        return count($this->group);
41 2
    }
42 2
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function current()
47 2
    {
48
        return current($this->group);
49 2
    }
50
51
    /**
52
     * Get the group size.
53
     *
54
     * @return int
55 2
     *             The size
56
     */
57 2
    public function getSize()
58 2
    {
59 2
        return (int) $this->size;
60
    }
61
62
    /**
63
     * {@inheritdoc}
64 2
     */
65
    public function next()
66 2
    {
67
        ++$this->key;
68
        next($this->group);
69
    }
70
71
    /**
72 2
     * Get the order.
73
     *
74 2
     * @param int $generator
75 2
     *                       The generator
76
     *
77
     * @return int
78
     *             The order
79
     */
80
    public function order($generator)
81
    {
82
        $result = [];
83 2
84
        foreach (range(1, $this->getSize()) as $number) {
85 2
            $value = ($generator ** $number) % $this->getSize();
86
            $result[$value] = $value;
87
        }
88
89
        return count($result);
90
    }
91
92
    /**
93
     * Set the group size.
94 2
     *
95
     * @param int $size
96 2
     *                  The size
97 2
     */
98 2
    public function setSize($size)
99
    {
100
        $this->size = $size;
101
        $this->computeGroup();
102
    }
103
104
    /**
105
     * {@inheritdoc}
106 2
     */
107
    public function valid()
108 2
    {
109
        return isset($this->group[$this->key()]);
110
    }
111
112
    /**
113
     * Clean out the group from unwanted values.
114
     */
115
    private function computeGroup()
116
    {
117
        $this->group = [];
118
119
        foreach (range(1, $this->getSize()) as $number) {
120
            if (1 === $this->gcd($number, $this->getSize())) {
121
                $this->group[] = $number;
122
            }
123
        }
124
    }
125
126
    /**
127
     * Get the greater common divisor between two numbers.
128
     *
129
     * @param int $a
130
     *               The first number
131
     * @param int $b
132
     *               The second number
133
     *
134
     * @return int
135 2
     *             The greater common divisor between $a and $b
136
     */
137 2
    private function gcd($a, $b)
138
    {
139 2
        return $b ? $this->gcd($b, $a % $b) : $a;
140 2
    }
141
}
142