Ruby中的项目Euler#3

时间:2013-12-26 20:08:35

标签: ruby

项目欧拉问题#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。谢谢!

6 个答案:

答案 0 :(得分:5)

以下是帮助您提高代码性能的一些指示(假设您的测试编号为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)}

答案 1 :(得分:1)

这个怎么样: -

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

答案 2 :(得分:1)

我认为这会更好:

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

答案 3 :(得分:1)

它也可以通过如下划分来解决:

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

答案 4 :(得分:0)

        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

答案 5 :(得分:0)

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

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