JavaScript - 项目Euler#5 - 效率

时间:2015-10-02 00:24:23

标签: javascript math

这是针对Project Euler,问题#5。

任务是找到可被1-8号整除的最小数字。我的代码似乎在1-18工作,但在19我的浏览器开始超时。这让我相信我的代码效率低下。

我该如何缓解这种情况?

function divisible(a){
    counter = 0;
    result = 2;
    while (counter < a){
        for (var x = 0; x <= a; x ++){
            if (result % x === 0){
                counter ++;
            }
        }
        if (counter != a){
            counter = 0;
            result ++;
        }
    }
    return result;
}
divisible(20)

3 个答案:

答案 0 :(得分:1)

是的,效率低下。您需要更改算法。我能想到的最有效的方法是将所有数字从2到20分解(有因子和计数:例如18是3 * 3 * 2,或者两次3和一次2,对于最终{ 3: 2, 2: 1 });然后找出每个因子的最大值,并将它们相乘。

一个缩写示例:可被18和16整除的最小数字:

18: { 3: 2, 2: 1 }
16: { 2: 4 }

maximums of factor repetitions: { 3: 2, 2: 4 }
result: 3^2 * 2^4 = 144

从2到20的因子分解很容易;如果您不知道如何操作,有许多可能的算法,您可以看到the Wikipedia article on integer factorisation的想法。

答案 1 :(得分:1)

基本上,您希望least common multiple为1,...,20。

我会使用gcd来实现lcm,这可以使用快速Euclidean algorithm来实现。

function gcd(a, b) {
  return b === 0 ? a : gcd(b, a%b); // Euclidean algorithm
}
function lcm(a, b) {
  return a * b / gcd(a, b);
}
function divisible(a){
  var result = 1;
  for(var i=2; i<=a; ++i)
    result = lcm(result, i);
  return result;
}
divisible(20); // 232792560

答案 2 :(得分:1)

  

另一种选择蛮力和模数休息分类

这个问题可以用一个简单的模数休息类特征来解决。 查看1到20之间的数字,并将其分为两组,并在它们之间找到一些独特的共同属性。

1 2 3 4 5 6 7 8 9 10

   we are building a division with the same reminder members

1除以所有

2划分4,8 - &gt;&gt; 8重要

3除以6,9但6不均匀地划分9 - &gt; 6,9

5划分10 - &gt;&gt; 10重要

让我们留下6,7,8,9,10来检查1中是否有任何数字可以将其与休息0分开。

诀窍是如果2,4,8除了一个数字,让16说同一个提醒,那么我们不必检查2,4分16,我们只检查8。

11 12 13 14 15 16 17 18 19 20

这里我们可以从上面的数字因素中做同样的事情,我们将留下

11 12 13 14 15 16 17 18 19 20

  

注意:我们知道必须除以数字的最后一个数字是20,   所以这意味着解决方案将是一个以0结尾的数字或者是   其中一个因素是20,所以我们建立20的因子并检查是否11 12   13 14 15 16 17 18 19可以分割它然后我们就完成了。

int start = 20;

    while (start % 11 != 0 || start % 12 != 0 | start % 13 != 0 || start % 14 != 0 || 
            start % 15 != 0 || start % 16 != 0 || start % 17 != 0 || start % 18 != 0 || start % 19 != 0 )
    {
        start += 20;
    }
    console.log(start)
  

同样的想法适用于我做的第一次演绎   问题似乎更小。

//最小数字可被1到10之间的所有数字整除

int a = 10;

    while (a % 6 != 0 || a % 7 != 0 | a % 8 != 0 || a % 9 != 0 )
    {
        a += 10;
    }

console.log(a)

//最小数字可被1到5之间的所有数字整除

int i = 5;                          

    while (i % 3 != 0 || i % 4 != 0)
    {
        i += 5;
    }

console.log(i)