CountSemiprimes::getKey()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 16
rs 9.2
cc 4
eloc 10
nc 3
nop 3
1
<?php
2
3
namespace Lesson09;
4
5
class CountSemiprimes
6
{
7
    public function solution($N, $P, $Q)
8
    {
9
        $initialArrayCount = count($P);
10
        $primes = array_values($this->filterPrimes($N, $this->getPrimes($N)));
11
        $primeCount = count($primes);
12
        $semiPrimes = $this->getSemiPrimes($N, $primeCount, $primes);
13
        ksort($semiPrimes);
14
15
        $assignableValue = 1;
16
        foreach ($semiPrimes as $value) {
17
            $semiPrimes[$value] = $assignableValue;
18
            $assignableValue++;
19
        }
20
21
        $semiPrimesInRange = [];
22
23
        for ($i = 0; $i < $initialArrayCount; $i++) {
24
            $pValue = $P[$i];
25
            $qValue = $Q[$i];
26
            $range = $qValue - $pValue;
27
28
            $leftKey = $this->getKey($pValue, $semiPrimes, $range);
29
            $rightKey = $this->getKey($qValue, $semiPrimes, $range);
30
31
            if ($leftKey === null || $rightKey === null) {
32
                $semiPrimesInRange[] = 0;
33
            } elseif ($rightKey === $leftKey) {
34
                $semiPrimesInRange[] = 1;
35
            } else {
36
                $semiPrimesInRange[$i] = $semiPrimes[$rightKey] - $semiPrimes[$leftKey] + 1;
37
            }
38
        }
39
40
        return $semiPrimesInRange;
41
    }
42
43
    /**
44
     * @param $N
45
     *
46
     * @return array
47
     */
48
    private function getPrimes($N)
49
    {
50
        $primes = [];
51
        for ($i = 2; $i <= $N; $i++) {
52
            $primes[$i] = $i;
53
        }
54
55
        return $primes;
56
    }
57
58
    /**
59
     * @param $N
60
     * @param $primes
61
     *
62
     * @return int
63
     */
64
    private function filterPrimes($N, $primes)
65
    {
66
        $initialValue = 2;
67
        while ($initialValue * $initialValue <= $N) {
68
            for ($j = $initialValue + $initialValue; $j <= $N; $j += $initialValue) {
69
                unset($primes[$j]);
70
            }
71
            $initialValue++;
72
        }
73
74
        return $primes;
75
    }
76
77
    /**
78
     * @param $N
79
     * @param $primeCount
80
     * @param $primes
81
     *
82
     * @return array
83
     *
84
     * @internal param $semiPrimes
85
     */
86
    private function getSemiPrimes($N, $primeCount, $primes)
87
    {
88
        $semiPrimes = [];
89
        for ($i = 0; $i < $primeCount; $i++) {
90
            for ($j = $i; $j < $primeCount; $j++) {
91
                $primesProduct = $primes[$i] * $primes[$j];
92
                if ($primesProduct <= $N) {
93
                    $semiPrimes[$primesProduct] = $primesProduct;
94
                } else {
95
                    break;
96
                }
97
            }
98
        }
99
100
        return $semiPrimes;
101
    }
102
103
    /**
104
     * @param $value
105
     * @param $semiPrimes
106
     * @param $range
107
     *
108
     * @return key
109
     */
110
    private function getKey($value, $semiPrimes, $range)
111
    {
112
        $key = null;
113
        if (array_key_exists($value, $semiPrimes)) {
114
            $key = $value;
115
        } else {
116
            for ($j = 1; $j <= $range; $j++) {
117
                if (array_key_exists($value + $j, $semiPrimes)) {
118
                    $key = $value + $j;
119
                    break;
120
                }
121
            }
122
        }
123
124
        return $key;
125
    }
126
}
127