【问题标题】:How can I optimize this Ruby code to run faster? [duplicate]如何优化此 Ruby 代码以更快地运行? [复制]
【发布时间】:2020-05-25 22:47:14
【问题描述】:

在从 m..n 的范围内,寻找除数平方和为完美平方的数字。返回数组中的数字和完美正方形。这是一个代码战挑战,只有由于超时而失败,测试本身就通过了。前任。 42 的除数是:1、2、3、6、7、14、21、42。这些除数的平方是:1、4、9、36、49、196、441、1764。平方除数的总和是 2500这是50 * 50,一个正方形。所以我会返回 [42, 2500]。

def list_squared(m, n)
  divisors = []
  matches = []

  # array of divisors for each num in the range
  (m..n).each do |num|
    divisors.push((1..num).select { |n| num % n == 0 })
  end

  # sum the squares of each array and push last element of the set, and perfect square to matches array
  divisors.each do |sets|
    sum = 0
    sets.each { |num| sum+=num**2 }
    if Math.sqrt(sum)%1 == 0
      matches.push([sets[-1],sum])
    end
  end
  return matches
end

【问题讨论】:

标签: ruby algorithm optimization


【解决方案1】:

在寻找因子时,您不需要检查从 1 到 num 的每个数字。
相反,检查从 1 到 sqrt(num) 的每个数字。
如果找到除数,请添加除数和 num/除数。
最后检查数字是否是一个完美的正方形。
如果是,请添加平方根

对于 42:
sqrt(42) 是 ~6.48
所以你只需要做 7 次检查而不是 42 次​​p>

n = 1 真
所以你加 1 和 42/1 = 42
n = 2 真
所以你加 2 和 42/2 = 21
n = 3 真
所以你加 3 和 42/3 = 14
n = 4 错误
n = 5 错误
n = 6 真
所以你加 6 和 42/6 = 7

现在 n 是 7
所以你检查 n*n 是否为 num
7*7 不是 42
你就完成了。

我对 Ruby 不是很精通,但它可能看起来像这样

def factors(num)
  divisors = []
  n = 1
  while n*n < num
    if num % n == 0
      divisors << n
      divisors << num/n
    end
    n += 1
  end
  if n*n == num
    divisors << n
  end
  divisors
end

至于除数平方的平方根,你可以在加除数的时候计算平方。

它可能看起来像这样

def is_perfect_square(num)
  square_of_divisors = 0
  n = 1
  while n*n < num
    if num % n == 0
      square_of_divisors += n**2 + (num/n)**2
    end
    n += 1
  end
  if n*n == num
    square_of_divisors += n**2
  end
  sqrt_divisors = Math.sqrt(square_of_divisors)
  sqrt_divisors == sqrt_divisors.to_i
end

所以,我修改后的代码是

def list_squared(m, n)
  matches = []

  (m..n).each do |num|
    square_of_divisors = 0

    k = 1
    while k*k < num
      if num % k == 0
        square_of_divisors += k**2 + (num/k)**2
      end
      k += 1
    end
    if k*k == num
      square_of_divisors += k**2
    end

    sqrt_divisors = Math.sqrt(square_of_divisors)
    if sqrt_divisors == sqrt_divisors.to_i
      matches << ([num, square_of_divisors.to_i])
    end
  end

  matches
end

同样,这可能不是最“Ruby”的方式,因此请根据自己的喜好进行修改。

我希望这会有所帮助。

【讨论】:

  • 欢迎来到 SO。请花时间正确格式化所有文本。这有助于其他人了解您的意图是什么,并且节省了我们试图破译它并将其变成其他人更容易理解的东西的时间。 “How do I format my posts...”和“How do I format my code blocks?”解释了为什么它很重要。
  • @theTinMan 谢谢。有什么特别难以破译的东西吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-25
  • 1970-01-01
  • 2021-08-05
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 2016-02-27
相关资源
最近更新 更多