projecteuler#3 Largest prime factor

* Prime.php

<?php
/**
https://projecteuler.net/problem=3
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
 */
class Prime {

    /** @var  int */
    private $value;

    public function __construct(int $value) {
        $this->value = $value;
    }

    public function isPrime(int $num) : bool {
        if ($num===2||$num===3) {return true;}

        //  for x >=1, 6x,6x+1,6x+2,6x+3,6x+4,6x+5
        // 6x+2,6x+3,6x+4 => 2(3x+1),3(2x+1),2(3x+2)
        if ($num % 6 !== 1 && $num % 6 !== 5) {return false;}
        for ($i = 5; $i * $i <= $num; $i += 6) {
            if ($num % $i === 0 || $num % ($i+2) ===0) {
                return false;
            }
        }

        return true;
    }

    private static function modMul(int $a, int $b, int $mod) : int {
        $res = 0;
        while ($b > 0) {
            if ($b & 1) {
                $res = ($res + $a) % $mod;
            }
            $a = ($a << 1) % $mod;
            $b >>= 1;
        }
        return $res;
    }

    private static function modPow(int $a, int $n, int $mod) : int {
        $res = 1;
        while ($n) {
            if ($n & 1) {
                $res = self::modMul($res, $a, $mod);
            }
            $a = self::modMul($a, $a, $mod);
            $n >>= 1;
        }
        return $res;
    }

    public static function millerRabin(int $n, int $loop = 20) : bool {
        if ($n===2) {return true;}
        if ($n < 2 || !($n & 1))
            return false;
        $m = $n - 1;
        $k = 0;
        while (!($m & 1)) {
            $k++;
            $m >>= 1;
        }
        // Miller-Rabin测试的迭代次数 $loop = 20
        while ($loop-- > 0) {
            $a = rand(0, $n-2) + 1;
            $x = self::modPow($a, $m, $n);
            $y = 0;
            for ($j = 0; $j < $k; $j++) {
                $y = self::modMul($x, $x, $n);
                if ($y === 1 && $x != 1 && $x != $n-1) {
                    return false;
                }
                $x = $y;
            }
            if ($y !== 1) {
                return false;
            }
        }
        return true;
    }

    public function getPrimeFactors() {
        $factors = [];

        if ($this->isPrime($this->value)) {
            return [ $this->value ];
        }
        // echo $this->value.' is not a prime number'.PHP_EOL;

        $last = ceil($this->value/2);
        $v = $this->value;

        for ($cur = 2; $cur <= $last && $cur <= $v; ) {
            if ($v % $cur === 0) {
                if ($this->isPrime($cur)) {
                    // echo $cur . PHP_EOL;
                    array_push($factors, $cur);
                    // echo implode(',', $factors) . PHP_EOL;
                }
                $v /= $cur;
            } else {
                $cur++;
            }
        }
        return $factors;
    }
}

// test:
// $ time php Prime.php
$prime = new Prime(600851475143);
$a = $prime->getPrimeFactors();  // [71, 839, 1471, 6857]
print_r($a);
echo $a[count($a)-1].PHP_EOL;  // 6857
// 0.042s

* test

$ time php Prime.php 

Array

(

    [0] => 71

    [1] => 839

    [2] => 1471

    [3] => 6857

)

6857

real 0m0.039s

user 0m0.020s

sys 0m0.010s

https://blog.csdn.net/ECNU_LZJ/article/details/72675595

https://blog.csdn.net/xxxxfengheheda/article/category/7995856

猜你喜欢

转载自blog.csdn.net/fareast_mzh/article/details/82958283