Reputation: 870
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.
Upvotes: 1
Views: 331
Reputation: 17
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
Upvotes: -1
Reputation: 34282
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.
Upvotes: 2