Passed
Push — master ( c380b2...9239b3 )
by Adrien
10:06
created

Lcm::factors()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 12
c 1
b 0
f 0
nc 8
nop 1
dl 0
loc 21
ccs 13
cts 13
cp 1
crap 5
rs 9.5555
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
4
5
use Exception;
6
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
7
8
class Lcm
9
{
10
    //
11
    //    Private method to return an array of the factors of the input value
12
    //
13 12
    private static function factors($value)
14
    {
15 12
        $startVal = floor(sqrt($value));
16
17 12
        $factorArray = [];
18 12
        for ($i = $startVal; $i > 1; --$i) {
19 12
            if (($value % $i) == 0) {
20 9
                $factorArray = array_merge($factorArray, self::factors($value / $i));
21 9
                $factorArray = array_merge($factorArray, self::factors($i));
22 9
                if ($i <= sqrt($value)) {
23 9
                    break;
24
                }
25
            }
26
        }
27 12
        if (!empty($factorArray)) {
28 9
            rsort($factorArray);
29
30 9
            return $factorArray;
31
        }
32
33 12
        return [(int) $value];
34
    }
35
36
    /**
37
     * LCM.
38
     *
39
     * Returns the lowest common multiplier of a series of numbers
40
     * The least common multiple is the smallest positive integer that is a multiple
41
     * of all integer arguments number1, number2, and so on. Use LCM to add fractions
42
     * with different denominators.
43
     *
44
     * Excel Function:
45
     *        LCM(number1[,number2[, ...]])
46
     *
47
     * @param mixed ...$args Data values
48
     *
49
     * @return int|string Lowest Common Multiplier, or a string containing an error
50
     */
51 18
    public static function funcLcm(...$args)
52
    {
53
        try {
54 18
            $arrayArgs = [];
55 18
            $anyZeros = 0;
56 18
            foreach (Functions::flattenArray($args) as $value1) {
57 18
                $value = Helpers::validateNumericNullSubstitution($value1, 1);
58 18
                Helpers::validateNotNegative($value);
59 18
                $arrayArgs[] = (int) $value;
60 18
                $anyZeros += (int) !((bool) $value);
61
            }
62 13
            if ($anyZeros) {
63 13
                return 0;
64
            }
65 5
        } catch (Exception $e) {
66 5
            return $e->getMessage();
67
        }
68
69 12
        $returnValue = 1;
70 12
        $allPoweredFactors = [];
71
        // Loop through arguments
72 12
        foreach ($arrayArgs as $value) {
73 12
            $myFactors = self::factors(floor($value));
74 12
            $myCountedFactors = array_count_values($myFactors);
75 12
            $myPoweredFactors = [];
76 12
            foreach ($myCountedFactors as $myCountedFactor => $myCountedPower) {
77 12
                $myPoweredFactors[$myCountedFactor] = $myCountedFactor ** $myCountedPower;
78
            }
79 12
            foreach ($myPoweredFactors as $myPoweredValue => $myPoweredFactor) {
80 12
                if (isset($allPoweredFactors[$myPoweredValue])) {
81 9
                    if ($allPoweredFactors[$myPoweredValue] < $myPoweredFactor) {
82 9
                        $allPoweredFactors[$myPoweredValue] = $myPoweredFactor;
83
                    }
84
                } else {
85 12
                    $allPoweredFactors[$myPoweredValue] = $myPoweredFactor;
86
                }
87
            }
88
        }
89 12
        foreach ($allPoweredFactors as $allPoweredFactor) {
90 12
            $returnValue *= (int) $allPoweredFactor;
91
        }
92
93 12
        return $returnValue;
94
    }
95
}
96