function q37() { $truncatablePrimes = []; $expected = 11; $generator = potentialTruncatablePrimeGenerator(); foreach ($generator as $potentialTruncatablePrime) { // echo $potentialTruncatablePrime . ' ' . $expected . PHP_EOL; if (!Number::isTruncatablePrime($potentialTruncatablePrime)) { continue; } --$expected; $truncatablePrimes[] = $potentialTruncatablePrime; if ($expected === 0) { break; } } return array_sum($truncatablePrimes); }
function q12($divisorCount) { // We can safely assume that the triangle number which is the sum of $divisorCount numbers // does not have $divisorCount divisors yet. $number = $divisorCount; while (true) { ++$number; $triangleNumber = Number::triangle($number); // It should be more likely that an even number be the first number to have more divisors, so lets skip uneven // numbers if ($triangleNumber & 1 !== 0) { continue; } $numberOfDivisors = Number::getDivisorsCount($triangleNumber); if ($numberOfDivisors > $divisorCount) { return $triangleNumber; } } }
function q44() { $pentagonalNumbers = []; $i = 0; while (true) { $pentagonalNumber = Number::pentagonal(++$i); $pentagonalNumbers[$pentagonalNumber] = $pentagonalNumber; foreach ($pentagonalNumbers as $firstPentagonalNumber) { $secondPentagonalNumber = $pentagonalNumber - $firstPentagonalNumber; if ($firstPentagonalNumber === $secondPentagonalNumber) { continue; } if (!isset($pentagonalNumbers[$secondPentagonalNumber])) { continue; } $difference = $secondPentagonalNumber - $firstPentagonalNumber; if (isset($pentagonalNumbers[$difference])) { return $secondPentagonalNumber - $firstPentagonalNumber; } } } }
function q45($t, $p, $h) { $px = Number::pentagonal($p); $tx = Number::triangle($t); while (true) { $hx = Number::hexagonal(++$h); $count = 1; while ($hx >= Number::pentagonal($p + 1)) { $px = Number::pentagonal(++$p); } if ($px === $hx) { ++$count; } while ($hx >= Number::triangle($t + 1)) { $tx = Number::triangle(++$t); } if ($tx === $hx) { ++$count; } if ($count === 3) { return $hx; } } }
function q23() { $limit = 28123; $lookup = []; for ($i = 1; $i < $limit; ++$i) { $isAbundant = Number::getProperDivisorsType($i) === 'abundant'; $lookup[$i] = $isAbundant; } $sum = 0; for ($i = 1; $i < $limit; ++$i) { $isSumOfAbundant = false; $maxToTest = (int) ceil($i / 2); for ($j = 1; $j <= $maxToTest; ++$j) { if ($lookup[$j] && $lookup[$i - $j]) { $isSumOfAbundant = true; break; } } if (!$isSumOfAbundant) { $sum += $i; } } return $sum; }
function q43() { // Compute the 3 digits values divisible by the given primes $primes = [2, 3, 5, 7, 11, 13, 17]; $divisibleBy = []; foreach ($primes as $prime) { $divisibleBy[$prime] = []; for ($i = $prime; $i < 1000; $i += $prime) { // Exclude any multiple of a given prime if it is already not pandigital if (!Number::isPandigital($i, null, true)) { continue; } $divisibleBy[$prime][] = $i; } } // Generate all the sequences of valid (respecting the constraint specified in the problem) pandigital numbers $primeSize = count($primes); $solutionSet = $divisibleBy[$primes[$primeSize - 1]]; for ($i = 1; $i < $primeSize; ++$i) { $upperPart = $divisibleBy[$primes[$primeSize - $i - 1]]; // dwdxdy $lowerPart = $solutionSet; // dxdydz // Map numbers for efficient matching $a = []; foreach ($upperPart as $number) { $formattedNumber = sprintf('%02d', $number % 100); $a[$formattedNumber][] = $number; } $b = []; foreach ($lowerPart as $number) { $formattedNumber = sprintf('%02d', floor($number / pow(10, $i))); $b[$formattedNumber][] = $number; } $intersection = array_intersect_key($a, $b); $newSolutionSet = []; foreach ($intersection as $key => $dontCare) { $upperPart = $a[$key]; $lowerPart = $b[$key]; foreach ($upperPart as $upper) { $upper = floor($upper / 100); foreach ($lowerPart as $lower) { $lower = sprintf('%0' . (2 + $i) . 'd', $lower); // Since the number has to be pandigital, make sure the digit we're about to add isn't already present if (strpos($lower, (string) $upper) !== false) { continue; } $value = $upper . $lower; $newSolutionSet[] = $value; } } } $solutionSet = $newSolutionSet; } // Find the last digit for each solution in the solution set $finalSolutionSet = []; foreach ($solutionSet as $solution) { for ($i = 0; $i < 10; ++$i) { if (strpos($solution, (string) $i) !== false) { continue; } $finalSolutionSet[] = $i . $solution; break; } } return array_sum($finalSolutionSet); }