Project Euler Problem 10 – Revisited (PHP)
Problem 10
The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
Script
Execution Time: 22.5509 seconds
Execution Time: 22.5509 seconds
Changes
Basically, all math functions went into a class first off. Then I basically had the array populated and removed multiples of each number in the array starting with lowest value and going up from there.
Basically, all math functions went into a class first off. Then I basically had the array populated and removed multiples of each number in the array starting with lowest value and going up from there.
I did run into an issue where I ran out of memory. This was solved by not including either even numbers or those divisible by 3 in the array. So the first number I worked with was 5 (4 was skipped because it was an even number.
I removed each multiple of 5 from the array of primes leaving 5 in the array. Once that was complete, I went on to the next value (7) and performed the same operations.
Doing the calculations in this manner saved approximately a full minute off the brute force method. I am sure there is an even faster way to calculate the value, but I am happy for now with the 22 seconds.
class.mathFunctions.php
class MathFunctions { public $v; private $arraySum; public function __construct() { $this->v = array(); $this->arraySum = 0; } /** * isPrime * * @param integer $n * @access public * @return void */ public function isPrime($n) { for ($x=2; $x<=sqrt($n); $x++) { if ($n%$x == 0) { return false; } } return true; } public function getPrimesBetween($a, $b) { if ($a == 1) $a++; if ($a == 2) { $this->v[$a] = 0; $a++; } if ($a == 3) { $this->v[$a] = 0; $a++; } for($x = $a; $x <= $b; $x++) { if ($x%2 != 0 && $x%3 != 0) { $this->v[$x] = 0; } } for($x = $a; $x <= $b/2; $x++) { $this->_removeNonPrimes($x); } } private function _removeNonPrimes($step) { $end = end($this->v); $end = key($this->v); for($x=$step*2; $x <= $end; $x += $step) { unset($this->v[$x]); } } public function getSumOfPrimesBetween($a, $b) { $this->getPrimesBetween($a, $b); array_walk($this->v, array($this, '_addArrayKeyValues')); return $this->arraySum; } private function _addArrayKeyValues($value, $key) { $this->arraySum += $key; } /** * isPandigital * * @param integer $n * @access public * @return boolean */ public function isPandigital($n) { if (is_array($n) === false) $n = str_split($n); $x = range(1, count($n)); $y = array_unique($n); sort($y); if (($x == $y) && (in_array(0, $x) === false)) { return true; } else { return false; } } /** * isPalindrome * * @param mixed $s * @access public * @return void */ public function isPalindrome($s) { if (is_array($s) === false) $s=str_split($s); $t = array_reverse($s); if ($s == $t) return true; else return false; } /** * isLychrel * * @param int $n * @param int $c * @access public * @return void */ function isLychrel($n, $c=0) { $x = str_split($n); $x = array_reverse($x); $x = join('', $x); $s = bcadd($x, $n); if ($this->isPalindrome($s) === true) { return false; } elseif($c >= 50) { return true; } return $this->isLychrel($s, ++$c); } }
p10.php
require_once 'class.mathFunctions.php'; $number = new MathFunctions; echo $number->getSumOfPrimesBetween(1, 2000000); echo PHP_EOL;