私はRuby=を学び、いくつかの数学のことをしています。私がやりたいことの1つは素数を生成することです。
最初の10個の素数と最初の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
end
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モジュールを含むため、フィルタリング、マッピングなど、あらゆる種類の楽しいことができます。
あなたがそれを自分でやりたいのなら、このようなものがうまくいくでしょう:
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
require 'prime'
Prime.first(10) # => [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
人々はすでに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 }
エラトステネスのふるいをチェックしてください。これはRuby固有ではありませんが、素数を生成するアルゴリズムです。このアルゴリズムの背後にある考え方は、数値のリスト/配列があるということです。
2..1000
最初の数値2を取得します。リストを調べて、2で割り切れるすべてのものを削除します。2以外の2で割り切れないすべてのもの(たとえば、[2,3,5,7,9、 11 ... 999]
次の数値3に進みます。そして、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
私はこれをコーディングカタのために行い、エラトステネスのふるいを使用しました。
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)
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
を返します。
ふるいアルゴリズムを実装する努力に行かなくても、平方根までの分割可能性を検証し、奇数をスキップするだけで、時間をすばやく節約できます。次に、数値を繰り返して、素数をチェックします。
覚えておいてください人間の時間>マシンの時間。
これは非常に大きな最大数の場合は高価な解決策になると思いますが、それ以外の場合はうまく機能するようです。
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
これは、素数または数学を使用せずに、「最大」引数までの素数をゼロから生成する方法です。どう考えているか教えてください。
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
エラトステネのふるいを実装(多かれ少なかれ)
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
数に素数を見つけますが、適応にはそれほどの労力は必要ないと思います。
質問自体とはまったく関係ありませんが、参考までに:
このスニペットで試してください:
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
のような、より複雑な別のジェネレータを使用することもできます。 詳細
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
これは、1行のコードで素数の配列を生成する超コンパクトなメソッドです。
def get_prime(up_to)
(2..up_to).select { |num| (2...num).all? { |div| (num % div).positive? } }
end