Ruby on rails 寻找600851475143的最大素因子

Ruby on rails 寻找600851475143的最大素因子,ruby-on-rails,ruby,algorithm,math,Ruby On Rails,Ruby,Algorithm,Math,我试图用一个程序来找到最大的素因子600851475143。这是针对Euler项目的: 我首先尝试使用以下代码执行此操作: #Ruby solution for http://projecteuler.net/problem=2 #Prepared by Richard Wilson (Senjai) #We'll keep to our functional style of approaching these problems. def gen_prime_

我试图用一个程序来找到最大的素因子600851475143。这是针对Euler项目的:

我首先尝试使用以下代码执行此操作:

    #Ruby solution for http://projecteuler.net/problem=2
    #Prepared by Richard Wilson (Senjai)

    #We'll keep to our functional style of approaching these problems.
    def gen_prime_factors(num) # generate the prime factors of num and return them in an array
      result = []
      2.upto(num-1) do |i| #ASSUMPTION: num > 3
        #test if num is evenly divisable by i, if so add it to the result.
        result.push i if num % i == 0
        puts "Prime factor found: #{i}" # get some status updates so we know there wasn't a crash
      end
      result #Implicit return
    end

#Print the largest prime factor of 600851475143. This will always be the last value in the array so:
puts gen_prime_factors(600851475143).last #this might take a while
这对于小数字来说很好,但是对于大数字来说,这需要很长的时间(和大量的内存)

现在我刚上过大学微积分课,但我已经很生疏了,从那以后就再也没学过数学了


我不想得到一个直截了当的答案,但我希望有人指出我需要的资源,或者告诉我需要学习什么来实现我在程序中看到的一些算法。

您的解决方案有几个问题。首先,你从来没有测试过
i
是素数,所以你只找到大数的最大因子,而不是最大的素数因子。有一个Ruby库可以使用,只需
要求“prime”
,您可以在条件中添加
&&i.prime?

这将修复程序中的不精确性,但仍然是缓慢和昂贵的(事实上,它现在将更加昂贵)。你可以做的一件很明显的事情就是设置
result=i
而不是执行
result.push i
,因为你最终只关心你找到的最后一个可行的
i
,所以没有理由维护所有主要因素的列表

然而,即便如此,它仍然非常缓慢。正确的程序应该几乎立即完成。关键是每次你找到一个主要因素时,都要缩小你要测试的数量。如果你已经找到了一个大数字的素因子
p
,那么你就不需要一直测试到大数字了。您要测试的“新”大数值是从大数值中尽可能多地除以
p
后剩下的数值:

big\u number=big\u number/p**n

其中,
n
是最大的整数,因此右侧仍然是一个整数。实际上,您不需要显式地找到这个
n
,只需一直除以
p
,直到您不再得到一个整数

最后,作为一个搅局者,我在下面提供了一个解决方案,但是如果你仍然想自己解决这个问题,你可以选择忽略它

require 'prime'

max = 600851475143; test = 3

while (max >= test) do
  if (test.prime? && (max % test == 0))
    best = test
    max = max / test
  else
    test = test + 2
  end
end

puts "Here's your number: #{best}"
练习:证明
测试.素数?
可以从
条件中消除。[提示:对于任何数字的最小(非1)除数,您能说些什么?]

练习:如果改为使用
max=600851475145
,则此算法速度较慢。如何提高
max
的任一值的速度?[提示:手工查找600851475145的素因式分解;这很容易做到,并且可以清楚地说明为什么当前算法对这个数字很慢]

为了学生的利益,也许您应该在扰流板中添加以下问题:(1)证明(我会使用归纳法)在while循环中,
max%test==0
表示
test.prime?
为真。(2) 计算
test.prime?
是否可能比计算
max%test==0快?这说明了包含这两个测试的价值是什么?(3) 如果将
max
更改为600851475145,会发生什么情况?如何解决此问题?需要“prime”才能实现此功能:
600851475145.prime\u division
。结果:
[[71,1],[839,1],[1471,1],[6857,1]]
。哈哈,太好了。是的,正确的方法是根据rici的评论消除显式的素性检查(也就是扰流板之后的第一个练习)。