简体   繁体   中英

Project Euler #32: Why is my answer wrong?

I am working on Problem 32 :

I have done a (mostly) brute force solution:

var main = function () {
    var total = 0
    for (var i = 0; i < 10000; i++) {
        for (var j = i; j < 10000; j++) {
            var temp = i * j;

            var fullString = "" + i.toString() + j.toString() + temp.toString();

            var allNums = fullString.split("").map(function(item) {
                return parseInt(item, 10);
            }).sort();

            if (allNums.length == 9) {
                var flag = 1
                for (var k = 1; k <= 9; k++) {
                    if (allNums[k - 1] != k) {
                        flag = 0;
                    }
                }

                if (flag) {
                    total++;
                }
            }
        }
    }
    return total;
}

console.log(main());

I consider it a pretty rare circumstance for the multiplicand, multiplier, and product to have unique digits from 1 to 9. So my answer of 9 seems reasonable to me. But looking at the online solutions the actual answer is 45228. Could someone explain where I went wrong here?

Thanks a lot.

In addition to counting the numbers instead of summing them, as hinted in the problem:

Some products can be obtained in more than one way so be sure to only include it once in your sum.

In particular,

18 * 297 = 5346
27 * 198 = 5346

which are both 1 through 9 pandigital.

So you need to remember the products you encounter from to avoid the duplicates:

var main = function () {
    var total = 0
    var seen = new Set();
    for (var i = 0; i < 10000; i++) {
        for (var j = i; j < 10000; j++) {
            var temp = i * j;

            var fullString = "" + i.toString() + j.toString() + temp.toString();

            var allNums = fullString.split("").map(function(item) {
                return parseInt(item, 10);
            }).sort();

            if (allNums.length == 9) {
                var flag = 1
                for (var k = 1; k <= 9; k++) {
                    if (allNums[k - 1] != k) {
                        flag = 0;
                    }
                }

                if (flag & !seen.has(temp)) {
                    total += temp;
                    seen.add(temp);
                }
            }
        }
    }
    return total;
}

Then the output is 45228, like expected.

The actual answer is 45228. However, if products are being repeated, we get 56370. Please check this out:

function identityIs1to9Pandigital(multiplicand,multiplier,product)
{
    var identity = `${multiplicand}${multiplier}${product}`.split('');
    if(identity.indexOf('0')> -1)//if there's a zero in it, it cannot be pandigital
    {return false;} 
    for(var i = 1; i <= 9; i++)//testing if number is 1 to 9 pandigital
    {
        var searchDigit = `${i}`; 
        var firstIndex  = identity.indexOf(searchDigit); 
        var lastIndex   = identity.lastIndexOf(searchDigit);  
        if(firstIndex !== lastIndex/*digit occurs more than once*/|| firstIndex < 0 || lastIndex < 0/*digit does not occur at all*/)
        {
            return false; 
        }
    }
    return true;  
}

var sum = 0; 
var pandigitalIdentities = [];//identities where multiplicand/multiplier/product are 1 to 9 pandigital
var pandigitalProducts = [];
for(var i = 1/*started from 1 since 1 to 9 pandigital cannot contain a 0*/; i < 10000; i++)
{
    for(var j = 1; j < 10000; j++)
    {
        if(i > j)//if it's a duplicate identity(for example, if we've already computed 1 *2, then there's no need for 2 *1)
        {}
        else
        {
            var multiplicand    = i; 
            var multiplier      = j; 
            var product         = multiplicand * multiplier;  
            if(identityIs1to9Pandigital(multiplicand,multiplier,product) && pandigitalProducts.indexOf(product) === -1)
            {
                sum+=product;
                pandigitalProducts.push(product); 
                pandigitalIdentities.push(`multiplicand:${multiplicand},multiplier:${multiplier},product:${product}\n`); 
            } 
        }  
    }
} 
console.log('sum: '+sum); 
//print the pandigital identities  
pandigitalIdentities.forEach(function(value, index, array) 
{
    console.log(value); 
});

The result of the console.log is shown below:

sum: 45228  
multiplicand:4,multiplier:1738,product:6952 
multiplicand:4,multiplier:1963,product:7852 
multiplicand:12,multiplier:483,product:5796 
multiplicand:18,multiplier:297,product:5346 
multiplicand:28,multiplier:157,product:4396 
multiplicand:39,multiplier:186,product:7254 
multiplicand:48,multiplier:159,product:7632 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM