我正在学习Ruby并做一些数学的东西。我想做的其中一件事是生成素数。
我想生成前十个素数而前十个素数。我测试一个数字是否是素数是没有问题的,但是想知道生成这些数字的最佳方法是什么?
我使用以下方法确定数字是否为素数:
class Integer < Numeric
def is_prime?
return false if self <= 1
2.upto(Math.sqrt(self).to_i) do |x|
return false if self%x == 0
end
true
end
end
答案 0 :(得分:46)
在Ruby 1.9中,有一个Prime类可用于生成素数,或测试数字是否为素数:
require 'prime'
Prime.take(10) #=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
Prime.take_while {|p| p < 10 } #=> [2, 3, 5, 7]
Prime.prime?(19) #=> true
Prime实现each
方法并包含Enumerable模块,因此您可以执行各种有趣的操作,如过滤,映射等。
答案 1 :(得分:10)
require 'prime'
Prime.first(10) # => [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
答案 2 :(得分:10)
如果你想自己做,那么这样的事情可以起作用:
class Integer < Numeric
def is_prime?
return false if self <= 1
2.upto(Math.sqrt(self).to_i) do |x|
return false if self%x == 0
end
true
end
def next_prime
n = self+1
n = n + 1 until n.is_prime?
n
end
end
现在获得前10个素数:
e = Enumerator.new do |y|
n = 2
loop do
y << n
n = n.next_prime
end
end
primes = e.take 10
答案 3 :(得分:7)
查看Eratosthenes筛选。这不是特定于Ruby的,但它是一种生成素数的算法。这个算法背后的想法是你有一个数字列表/数组说
2..1000
你抓住第一个数字,2。浏览列表并删除可被2整除的所有内容。你将留下除2之外不能被2整除的所有内容(例如[2,3,5,7] ,9,11 ... 999]
转到下一个数字,3。再次,消除你可以除以的所有东西。继续前进,直到你到达最后一个数字,你将得到一个素数数组。希望有所帮助。
答案 4 :(得分:7)
人们已经提到了Prime
类,这绝对是可行的方法。有人还向您展示了如何使用Enumerator,我想使用Fiber贡献一个版本(它使用您的Integer#is_prime?
方法):
primes = Fiber.new do
Fiber.yield 2
value = 3
loop do
Fiber.yield value if value.is_prime?
value += 2
end
end
10.times { p primes.resume }
答案 5 :(得分:3)
# First 10 Prime Numbers
number = 2
count = 1
while count < 10
j = 2
while j <= number
break if number%j == 0
j += 1
end
if j == number
puts number
count += 1
end
number += 1
end
答案 6 :(得分:1)
实施了Eratosthene筛选(或多或少)
def primes(size)
arr=(0..size).to_a
arr[0]=nil
arr[1]=nil
max=size
(size/2+1).times do |n|
if(arr[n]!=nil) then
cnt=2*n
while cnt <= max do
arr[cnt]=nil
cnt+=n
end
end
end
arr.compact!
end
此外这是一个我很喜欢的单行
def primes_c a
p=[];(2..a).each{|n| p.any?{|l|n%l==0}?nil:p.push(n)};p
end
当然,那些会在第一个n
数字中找到素数,而不是第一个n
素数,但我认为改编不需要太多努力。
答案 7 :(得分:1)
这是一种生成素数的方法,直到&#34; max&#34;从头开始的论证,不使用Prime或Math。让我知道你的想法。
def prime_test max
primes = []
(1..max).each {|num|
if
(2..num-1).all? {|denom| num%denom >0}
then
primes.push(num)
end
}
puts primes
end
prime_test #enter max
答案 8 :(得分:1)
我认为对于非常大的最大数字,这可能是一个昂贵的解决方案,但似乎效果不错:
def multiples array
target = array.shift
array.map{|item| item if target % item == 0}.compact
end
def prime? number
reversed_range_array = *(2..number).reverse_each
multiples_of_number = multiples(reversed_range_array)
multiples_of_number.size == 0 ? true : false
end
def primes_in_range max_number
range_array = *(2..max_number)
range_array.map{|number| number if prime?(number)}.compact
end
答案 9 :(得分:1)
class Numeric
def prime?
return self == 2 if self % 2 == 0
(3..Math.sqrt(self)).step(2) do |x|
return false if self % x == 0
end
true
end
end
这样,现在3.prime?
返回true
,6.prime?
返回false
。
如果不努力实施筛分算法,只需验证可分性直到平方根并跳过奇数,就可以快速节省时间。然后,遍历数字,检查完整性。
记住:人类时间&gt;机器时间。
答案 10 :(得分:1)
我为编码kata做了这个,并使用了Eratosthenes的Sieve。
puts "Up to which number should I look for prime numbers?"
number = $stdin.gets.chomp
n = number.to_i
array = (1..n).to_a
i = 0
while array[i]**2 < n
i = i + 1
array = array.select do |element|
element % array[i] != 0 || element / array[i] == 1
end
end
puts array.drop(1)
答案 11 :(得分:0)
Ruby:打印N素数 http://mishra-vishal.blogspot.in/2013/07/include-math-def-printnprimenumbernoofp.html
include Math
def print_n_prime_number(no_of_primes=nil)
no_of_primes = 100 if no_of_primes.nil?
puts "1 \n2"
count = 1
number = 3
while count < no_of_primes
sq_rt_of_num = Math.sqrt(number)
number_divisible_by = 2
while number_divisible_by <= sq_rt_of_num
break if(number % number_divisible_by == 0)
number_divisible_by = number_divisible_by + 1
end
if number_divisible_by > sq_rt_of_num
puts number
count = count+1
end
number = number + 2
end
end
print_n_prime_number
答案 12 :(得分:0)
与问题本身完全无关,但仅供参考:
尝试使用此代码段:
require 'prime'
for p in Prime::Generator23.new
# `p` brings subsequent prime numbers until the end of the days (or until your computer explodes)
# so here put your fabulous code
break if #.. I don't know, I suppose in some moment it should stop the loop
end
fp
如果您需要它,您还可以使用另一个更复杂的生成器Prime::TrialDivisionGenerator
或Prime::EratosthenesGenerator
。 More info
答案 13 :(得分:0)
这是一种超级紧凑的方法,可以用一行代码生成素数数组。
def get_prime(up_to)
(2..up_to).select { |num| (2...num).all? { |div| (num % div).positive? } }
end
答案 14 :(得分:-1)
def get_prime(number)
(2..number).each do |no|
if (2..no-1).all? {|num| no % num > 0}
puts no
end
end
end
get_prime(100)