【问题标题】:Project Euler #3 in RubyRuby 中的 Euler 项目 #3
【发布时间】:2013-12-26 20:08:34
【问题描述】:

欧拉计划问题#3:

13195 的质因数是 5、7、13 和 29。600851475143 的最大质因数是多少?

def is_prime?(number)
    prime = true
    (2...number).each { |x|
        prime = false if number % x == 0
    }
    prime
end

def largest_prime(number)
    primes = []
    (number.downto(1)).each {|x|
        primes.push(x) if number % x == 0 && is_prime?(x)
        break if primes.count == 1
    }
    primes[0]
end

我的答案是用 Ruby 编写的。该代码适用于较小的数字但不适用于较大的数字,任何人都可以解释到底发生了什么以及如何解决它?我见过其他人有这个问题——很抱歉重新发布——但我是一个编程新手,我并不真正理解他们的答案,也没有看到任何其他用 Ruby 回答的帖子。谢谢!

【问题讨论】:

标签: ruby


【解决方案1】:

这里有一些提示可以帮助你提高代码的性能(假设你的测试号是n):

  • 仅执行从2square_root(n) 的可分性测试。在这个范围内,任何大于square_root(n) 的数字都已被覆盖。数学思考:)
  • 任何不是2的偶数都不是素数!
  • 使用prime sieve 可以大大提高您的主要测试算法的性能。

但是,不要这样做:

  • 因为您解决欧拉问题是为了娱乐和学习,所以不要使用 ruby​​ 提供的 prime 库。

这是我用来解决这个问题的两个助手(我在刚接触 ruby​​ 的时候就写过它们,可能效率不高,例如他们不使用我建议的 sieve) :

def lower_divisors_of(n)
  data = (2..(Math.sqrt(n).to_i)).select{ |a| n % a == 0 }
  data.map{|a| [a, n/a]}.flatten.sort.reverse
end

def is_prime?(n)
  lower_divisors_of(n).empty?
end

lower_divisors_of(n).detect{|i| is_prime?(i)}

【讨论】:

    【解决方案2】:

    这个怎么样:-

    require "prime"
    
    def problem_three(num)
        last_prime = num.prime_division.last # This will give us [6857, 1]
        # We only want the first one
        last_prime[0] # or last_prime.first
    end
    
    puts problem_three(600851475143)
    

    答案是:-

    $ ruby problem_three.rb
      6857
    

    【讨论】:

      【解决方案3】:

      我认为这会更好:

      require 'prime'
      puts Prime.prime_division(600851475143).last[0]
      

      【讨论】:

        【解决方案4】:

        也可以通过除法解决:

        def largest_prime(number)
        i = 2
        largest_divisor = 0
          while i < number
            if number % i == 0
              largest_divisor = i
              number = number / i
              i = 2
            else
              i += 1
            end
          end
        number
        end
        

        【讨论】:

          【解决方案5】:
                  t = Time.now
          
          class Fixnum
              def add
                  X[ X.length ] = self
              end
          
              def prime
              prime = true
                  i = 0
                  k = Math.sqrt(self)
                  while (k >= X[i]) do            
                      if self % X[i] == 0 then
                          prime = false
                          break
                      end
                      i +=1
                  end
                  if prime then
                      self.add
                  end
                  return prime
              end
          
              def prime2 
                prim =true
                2.upto(Math.sqrt(self)) do
                 |i|
                 if self % i == 0 then
                  prim =false
                  break
                 end
                end  
                return prim
               end    
          end
          
          ################ Here the code starts:
          X = []
          2.add
          
          3.upto(10000) { |i| i.prime}
          
          a = 600851475143
          i = 0
          while a != 1 do
              if (a % X[i] == 0) then 
                  while a % X[i] == 0 do
                      a = a / X[i]
                  end
              else
                  i +=1
              end
          end
          puts X[i]
          
          result = 6857
          14.219256 ms
          

          【讨论】:

          • 这里的解释非常合适。
          【解决方案6】:

          这是我能找到的最简单的算法

          def lpf(n)
            i = 2
            while i * i <= n
                while n % i == 0
                    n = n / i
                    break if n == i
                end
                i += 1
            end
            n
          end
          
          p lpf(600851475143) # => 6857
          

          【讨论】:

            猜你喜欢
            • 2012-11-10
            • 2020-10-30
            • 2015-05-04
            • 2019-10-24
            • 2023-03-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多