Exemplo n.º 1
0
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);
}