Sieve of Eratosthenes in Ruby

前端 未结 5 1919
眼角桃花
眼角桃花 2020-12-14 20:10

Rather than scraping a Ruby version of this algorithm off the net I wanted to create my own based on its description here. However I cannot figure out two things

<         


        
5条回答
  •  青春惊慌失措
    2020-12-14 20:35

    There's a faster implementation at www.scriptol.org:

    def sieve_upto(top)
      sieve = []
      for i in 2 .. top
        sieve[i] = i
      end
      for i in 2 .. Math.sqrt(top)
        next unless sieve[i]
        (i*i).step(top, i) do |j|
          sieve[j] = nil
        end
      end
      sieve.compact
    end
    

    I think it can be improved on slightly thus:

    def better_sieve_upto(n)
      s = (0..n).to_a
      s[0] = s[1] = nil
      s.each do |p|
        next unless p
        break if p * p > n
        (p*p).step(n, p) { |m| s[m] = nil }
      end
      s.compact
    end
    

    ...largely because of the faster array initialisation, I think, but it's marginal. (I added #compact to both to eliminate the unwanted nils)

提交回复
热议问题