【问题标题】:Ruby Prime Factors红宝石素数
【发布时间】:2016-04-07 15:09:54
【问题描述】:

我见过用其他语言发布的解决方案,但不是 Ruby,所以我在这里问。

试图找出最大的质因数 13195。

我的代码如下

    # find out all numbers that divide without remainder into 13195

    array = []
    count = 2

    13195.times do 
        if 13195 % count == 0
            array.push(count)   
        end
        count += 1
    end



    #From those numbers that divide cleanly into 13195, find out which are prime aka can only be divided by themselves and 1

    new_count = 2
    primes = 0

    array.each do |x|
        while new_count < x 
            if x % new_count != 0
            else
                if x > primes
                primes = x
            end
            end
        new_count += 1
        end
    end

     puts primes

在我的第一个循环中,我正在填充一个空数组,其中包含除 13195 且没有余数的所有数字,从测试这段代码似乎可以正常工作。

我的解决方案的第二部分是我每个语句中的问题,有人可以指出我正确的方向吗?

【问题讨论】:

    标签: ruby prime-factoring


    【解决方案1】:

    我建议你使用Prime#prime_division:

    require 'prime'
    
    def largest_prime_factor(n)
      Prime.prime_division(n).max_by(&:first).first
    end
    
    largest_prime_factor(13195)
      #=> 29
    
    (1..1000).to_a.sample(15).sort.each {|n| puts "%3d: %3d" % [n, largest_prime_factor(n)]}
     61:  61
     80:   5
     88:  11
    250:   5
    304:  19
    414:  23
    514: 257
    548: 137
    679:  97
    716: 179
    754:  29
    770:  11
    906: 151
    907: 907
    968:  11
    

    例如,

    n = 13195
    a = Prime.prime_division(n)
      #=> [[5, 1], [7, 1], [13, 1], [29, 1]] 
    b = a.max_by(&:first)
      #=> [29, 1] 
    b.first
      #=> 29 
    

    prime_division 返回的数组元素似乎按素数递增的顺序排列。如果可以保证,可以写:

    Prime.prime_division(n).last.first
    

    如果这些元素的顺序是特定于实现的,我使用了max_by

    【讨论】:

      【解决方案2】:

      短版:

      require 'prime'
      primes = Prime.each(13195).to_a
      upper = primes.last
      

      primes 将包含从 0 到 13195 的所有素数,显然是最后一个。

      【讨论】:

      • 想要的不是最大到 13195 的素数,而是 131195 的最大素数。
      • @CarySwoveland 你说得对,我没看错,是它想要的因子的“树”
      【解决方案3】:

      我将质数的限制设置为 100000(以避免几天计算 600851475143 = 等大数)

      def prime_factors(n)
        prime_array = []    
        p = 2
        if n < 2
            return p
        end
      
      
        while p < n && p < 1000000
          if n % p == 0
            prime_array.push(p)
          end
        p +=1
        end
      
        primes = []
      
        prime_array.size.times do |i|
          if n > 1
            n = n / prime_array[i]
            primes.push(prime_array[i])
          end
        end
        return primes.last
      end
      
      #prime_factors(600851475143)
      puts prime_factors(600851475143)
      
      #prime_factors(13195)
      puts prime_factors(13195)
      

      【讨论】:

        【解决方案4】:

        prime_division 的另一种使用方式:

        require 'prime'
        (13195).prime_division.map(&:first).max
        => 29
        

        【讨论】:

          【解决方案5】:

          您的第二个循环可以重新编写以执行应执行的操作。

          据我了解,您的目标是从array 中选择最大的素数元素(仅除以 1 和自身)。换句话说,如果元素x 不能被2x-1 之间的任何数字整除,则它是合格的。

          result = array.select {|x| not (2..x-1).any? {|i| x % i  == 0} }.max
          #=> 29
          

          目前,您的逻辑存在一些缺陷。它不会重置 new_count 的值,因此您会得到错误的结果。这是修正版:

          array.each do |x|
              is_prime = true
              while new_count < x 
                  if x % new_count == 0
                      is_prime = false
                  end
                  new_count += 1
              end
              new_count = 2
              primes = x if is_prime and x > primes
          end
          

          【讨论】:

          • 完美。我以前使用过 select 和 any ,但我从来没有想过要像这样组合它们。看来我还有很长的路要走。干杯!
          • @Sevenum 欢迎来到 StackOverflow!如果有帮助,请不要forget to accept an answer
          • 谢谢,真是个好地方。我想知道,因为我认为您给出的答案是高级答案,是否可以像我最初尝试的那样使用 each 和 if 来完成?
          • @Sevenum 可以,你当前的循环逻辑不正确-我已经更新了答案
          【解决方案6】:

          不使用Prime#prime_division,我们可以将问题分解为小部分。第一部分如果编写一个方法来确定一个数字是否为素数,可以像:

          def prime?(num)
          
              if num < 2
                  return false
              end
             (2...num).each do |ele|
                if num % ele == 0 
                  return false
                end
             end
            return true
          end
          

          然后我们可以编写我们的 main 方法,它要求一个数字的 prime_factors,例如:

          def prime_factors(num)
          
          prime_facts = []
          
          (1..num).each do |i|
              if  num % i == 0 && prime?(i)
                  prime_facts << i
              end
          end
          return prime_facts
          end 
          
          print prime_factors(24) #=> [2, 3]
          puts
          print prime_factors(60) #=> [2, 3, 5]
          puts
          print prime_factors(13195) # [5, 7, 13, 29]
          puts
          

          【讨论】:

            猜你喜欢
            • 2019-08-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-21
            • 1970-01-01
            • 2015-01-21
            • 2010-09-09
            • 1970-01-01
            相关资源
            最近更新 更多