Reputation: 870
I am working on Problem 29:
How many distinct terms are in the sequence generated by ab for 2 ≤ a ≤ 100 and 2 ≤ b ≤ 100?
I have done a brute force solution with a filter:
var main = function() {
var arr = [];
for (var a = 2; a <= 100; a++) {
for (var b = 2; b <= 100; b++) {
arr.push(BigInt(Math.pow(a, b)));
}
}
//arr.sort((a, b) => a - b);
return arr.filter(function(elem, pos) {
return arr.indexOf(elem) == pos;
}).length;
}
console.log(main());
My program executes fine. Although the result I am getting is 9220
where as the correct answer is 9183
. What am I missing here?
Upvotes: 2
Views: 695
Reputation: 370979
The problem is that
BigInt(Math.pow(a, b))
Even with BigInt, the expression inside it gets evaluated before it gets passed to BigInt, and Javascript cannot precisely handle huge numbers. The behavior looks to be browser-dependent, unfortunately, the problem is not sufficiently reproducible on every environment.
For a cross-browser solution, you'll have to find another method, like finding the distinct factors of each number, and filtering out numbers with duplicate factor counts. (eg, 2^4's prime factors are 2x2x2x2, same as 4^2 - filter out all such duplicates.)
For example:
const isPrime = num => {
for(let i = 2; i < num; i++)
if(num % i === 0) return false;
return num > 1;
}
const primes = Array.from(
{ length: 100 },
(_, i) => i + 1
).filter(isPrime);
const addPrimesToObj = (num, prime, obj) => {
while ((num / prime) % 1 === 0) {
obj[prime] = (obj[prime] || 0) + 1;
num = num / prime;
}
return num;
};
var main = function() {
const factorsSet = new Set();
for (let a = 2; a <= 100; a++) {
for (let b = 2; b <= 100; b++) {
const theseFactors = {};
for (let i = 0; i < b; i++) {
let innerA = a;
primes.forEach((prime) => {
innerA = addPrimesToObj(innerA, prime, theseFactors);
});
}
const factorsStr = Object.entries(theseFactors)
.map(([key, val]) => `${key}-${val}`)
.join('_');
factorsSet.add(factorsStr);
}
}
return factorsSet.size;
}
console.log(main());
Upvotes: 1
Reputation: 92517
BigInt have sufficient (arbitrary) precision (support by chrome)
var main = function() {
var arr = [];
for (var a = 2; a <= 100; a++) {
var p= BigInt(a);
for (var b = 1; b <= 100; b++) {
if(b>=2) arr.push(p);
p=p*BigInt(a);
}
}
return arr.filter(function(elem, pos) {
return arr.indexOf(elem) == pos;
}).length;
}
console.log(main());
Upvotes: 1
Reputation: 12152
Convert the array to a set, all duplicates will be removed automatically. Return the size of the set
var main = function() {
var arr = [];
for (var a = 2; a <= 100; a++) {
for (var b = 2; b <= 100; b++) {
arr.push(BigInt(Math.pow(a, b)));
}
}
//arr.sort((a, b) => a - b);
var e=new Set(arr);
return e.size()
}
console.log(main());
Upvotes: -1