因此,当我丢失所有代码时,我重新启动了 Project Euler。我遇到了问题 23。我知道该怎么做,我以前也做过,但现在不行,我一直在努力解决它很长时间,我几乎无法直截了当地思考。这次我使用的是 NodeJS。
根据这篇真正简化的文章,我可以使用素数分解来计算一个数字的除数之和。所以我有这两个功能:
Util.GetPrimeFactors = function (val) {
var init = val;
var num = 2;
var primes = {};
while (val > 1) {
if (val % num == 0) {
if (num == init) return [];// prevent prime numbers from including themselves
if (primes[num]) {
primes[num]++;
} else {
primes[num] = 1;
}
val /= num;
} else {
num++;
}
}
return primes;
}
Util.SumOfDivisors = function (val) {
var primes = Util.GetPrimeFactors(val);
var coeff = primes[0];
var count = 0;
var total = 1;
for (var i in primes) {
count++;
if (primes[i] > 1) {
var n = parseInt((Math.pow(parseInt(i), primes[i] + 1) - 1) / (parseInt(i) - 1))
console.log(n);
total *= n;
} else {
var n = parseInt(i) + 1
console.log(n);
total *= n;
}
}
if (count == 1) return 1;
return total;
}
如果我打电话GetPrimeFactors(12)
,我会得到这个对象:{ '2': 2, '3': 1 }
它代表2^2+3
,名称是基值,值是指数。SumOfDivisors
使用该对象在上面链接的文章中进行数学运算。问题是根据 Project Euler 问题,12 是第一个丰富的数字。如果我通过 6 运行SumOfDivisors
,我会得到正确的素因子(对象{ '2': 1, '3': 1 }
),但它会导致 SumOfDivisors 返回 12,从而使 6 看起来很丰富。如果您以低效的方式将因数相加(数学文章中的项目 B),那么您显然会得到因数 1、2 和 3,这使 6 成为完美数。
我记得在我的旧 C# 代码中,我使用了相同的技术:查找素数并使用它们对除数求和。但是我没有这个问题 6 (可能还有更多的数字)。我在这里做错了什么,我很茫然。当我找到除数的总和时,我做错了什么?是否已知这种技术不适用于某些值?我是否对特殊情况感到震惊?我是否陷入了 Javascript 陷阱?