ОКОНЧАТЕЛЬНОЕ РЕДАКТИРОВАНИЕ
Вот код PHP из логики Бакудана, который возвращает этот результат:
start time:44:25:000000
#10001: 104759
End time:44:26:000000
Код:
<?php
echo "start time:" . date("i:s:u") . "\n";
function isPrime($number, &$primes)
{
if ($number === 1) return false;
elseif ($number %2 === 0) return false;
elseif ($number < 4) return true;
elseif ($number < 9) return true;
elseif ($number %3 === 0) return false;
else $r = floor(sqrt($number));
$f = 5;
while ($f <= $r) {
if ($number % $f ===0) return false;
if ($number % ($f+2) === 0) return false;
$f = $f + 6;
}
return true;
}
$primes = array();
$nbPrimes = $i = 0;
while ($nbPrimes < 10001)
{
$i++;
if (isPrime($i, $primes) !== false)
{
$primes[] = $i;
$nbPrimes++;
}
}
echo "#$nbPrimes: " . end($primes) . "\n";
echo "End time:" . date("i:s:u") . "\n";
Бакудан дал мне псевдокод, который я только что перевел и написал для сценария ОП выше.
РЕДАКТИРОВАТЬ 2
Я немного очистил код, ничего не улучшил, может улучшить «читабельность». Но да, я думаю, что это лучшее, что вы получите с PHP, который на i7 без apache дает 5 секунд.
<?php
echo "start time:" . date("i:s:u") . "\n";
function isPrime($number, &$primes)
{
foreach($primes as $prime) {
if ($number % $prime === 0 && $prime > 1)
return false;
}
}
$primes = array();
$nbPrimes = $i = 1;
while ($nbPrimes <= 10001)
{
if ($i % 2 !== 0 && isPrime($i, $primes) !== false)
{
$primes[] = $i;
$nbPrimes++;
}
$i++;
}
echo "#$nbPrimes: " . end($primes) . "\n";
echo "End time:" . date("i:s:u") . "\n";
EDIT
Сбил еще одну секунду, переместив $prime === 1
в положение после проверки $number % $prime
в том же операторе if
.
start time:29:40:000000
#10001: 104743
End time:29:45:000000
Принятие предложения Ханнеса о строгой проверке и передаче массива в качестве ссылки, плюс добавление нескольких собственных настроек (изменение массива внутри функции):
ini_set('max_execution_time', 300);
echo "start time:" . date("i:s:u") . "\n";
function isPrime($number, &$prevPrimes)
{
foreach ($prevPrimes as $prime) {
if ($number % $prime === 0 && $prime !== 1)
{
return false;
}
}
// If we get to here, $number is prime
$prevPrimes[] = $number;
return $number;
}
$primes = array();
$i = 0;
$nbPrimes = 0;
while ($nbPrimes < 10001)
{
$i++;
if ($i % 2 !== 0)
{
$result = isPrime($i, $primes);
if ($result !== 0)
{
$nbPrimes++;
}
}
}
echo "#$nbPrimes: $result\n";
echo "End time:" . date("i:s:u") . "\n";
Который в итоге оказался:
start time:52:08:000000
#10001: 104743
End time:52:15:000000
VS ваш код:
start time:50:44:000000
#10001: 104743
End time:51:17:000000
Хорошее улучшение, но ничего похожего на C #, просто показывает мощь скомпилированного языка:)