我正在用ruby编写一个程序,以查找给定数字的所有素数。我知道ruby有一个.Prime类,但我想在不使用它的情况下完成它。
除了一个问题外,一切都很好:我找不到对一系列数字进行模运算的方法。我试着在网上、Ruby文档和这里的旧帖子中找到答案。到目前为止,我没有发现任何帮助。
这是代码:
def prime(n)
r = Range.new(2, n-1)
r.each { |x| puts x if n % x == 0 && x % (2..x-1) != 0}
end
print "Please enter a number: "
prime(gets.chomp.to_i)
编辑:对不起,我可能含糊其辞。这段代码:
x % (2..x-1) != 0
反击:
euler2.rb:3:in `%': Enumerator can't be coerced into Fixnum (TypeError)
from euler2.rb:3:in `block in divisible'
from euler2.rb:3:in `each'
from euler2.rb:3:in `divisible'
from euler2.rb:7:in `<main>'
我在谷歌上搜索过那个错误,但运气不好。如果我将代码更改为非范围,它就会起作用。
您的逻辑不正确。你可以尝试更简单的东西,比如:
def prime(n)
!(2..n-1).detect{|x| n%x == 0}
end
这里detect将返回与条件n%x == 0
相匹配的x
的第一个值。如果没有匹配,则返回nil
。因此,在素数的情况下,(2..n-1).detect{|x| n%x == 0}
将返回nil
,而!
将使其成为true
。对于复数,它们的最低除数将被返回,!
将使其成为false
。
您的代码出了什么问题
你正在做x % (2..x-1)
。这里(2..x-1)
是一个范围。不能用Range对Fixnum进行模运算。因此,您将获得:
TypeError: Range can't be coerced into Fixnum
您可以使用类似(2..x-1).each{|n| x%n}
或任何其他枚举器来代替each
来改进x % (2..x-1)
。然而,我仍然认为你的逻辑过于复杂或是像这样一个简单的问题。
any?
怎么样?
def prime(n)
range = Range.new(2, n-1)
composite = range.any? { |i| n%i == 0 }
!composite
end
当然,对于大量的人来说,这将是缓慢的。