优化(CodeWars整数:娱乐一)

时间:2018-07-29 13:15:46

标签: javascript algorithm optimization

我设法为CodeWars挑战(https://www.codewars.com/kata/integers-recreation-one/train/javascript)找到了两个算法。不幸的是,它们不够快(> 12000ms)。

关于如何改进我的代码的任何建议?

v1:

const listSquared = (m, n) => {
  const result = [];
  for (let i = m; i <= n; i++) {
    const divisorsOfi = [];
    for (let j = 0; j <= i; j++) {
      if (i % j === 0) {
        divisorsOfi.push(Math.pow(j, 2))
      }
    }
    let sumOfDivisorsOfi = 1;
    if (divisorsOfi.length > 1) {
      sumOfDivisorsOfi = divisorsOfi.reduce((a, b) => a + b);
    }
    if (Number.isInteger(Math.sqrt(sumOfDivisorsOfi))) {
      result.push([i, sumOfDivisorsOfi]);
    }
  }
  return result;
}

v2:

const listSquared = (m, n) => {
  const result = [];
  for (let i = m; i <= n; i++) {
    let sumOfSqrtDivisorsOfi = divisors(i);
    if (Number.isInteger(Math.sqrt(sumOfSqrtDivisorsOfi))) {
      result.push([i, sumOfSqrtDivisorsOfi]);
    }
  }
  return result;
}

const divisors = (n) => [...Array(n + 1).keys()].slice(1)
.reduce((s, a) => s + (!(n % (a)) && Math.pow(a, 2)), 0);

谢谢!

1 个答案:

答案 0 :(得分:0)

我以 v1 为基础,并通过以下方式对其进行了修改

const listSquared = (m, n) => {
  const result = [];
  for (let i = m; i <= n; i++) {
    const divisorsOfi = [];
    for (let j = 0; j <= Math.sqrt(i); j++) {
      if (i % j === 0) {
        divisorsOfi.push(Math.pow(j, 2));
        if (i/j != j)
          divisorsOfi.push(Math.pow(i/j, 2));

      }
    }
    let sumOfDivisorsOfi = 1;
    if (divisorsOfi.length > 1) {
      sumOfDivisorsOfi = divisorsOfi.reduce((a, b) => a + b);
    }
    if (Number.isInteger(Math.sqrt(sumOfDivisorsOfi))) {
      result.push([i, sumOfDivisorsOfi]);
    }
  }
  return result;
}

这里的想法很简单:如果 a 可以除以 j ,那么也可以除以 a / j ,因此我们只需要检查sqrt(a)的第一个数字。唯一需要注意的是,如果 a / j j 是相同的数字,则对结果进行两次计数。