[英]How can I find all prime numbers below a given input value?
I have been tasked with finding all the prime numbers in Ruby (without using the prime method)我的任务是在 Ruby 中查找所有质数(不使用质数方法)
Below is my logic, the issue, my code and the output.下面是我的逻辑、问题、我的代码和输出。
My Logic:我的逻辑:
All primes have only 2 distinct divisors.所有素数只有 2 个不同的除数。 Hence if we count the number of divisors a number has and it is greater than 2, then it is not prime (apart from 1, which I havn't dealth with yet)
因此,如果我们计算一个数的除数数并且它大于 2,那么它就不是质数(除了 1,我还没有处理过)
Therefore I have made an array, filled it with all the numbers from 1 – 10 (I'll do 1000 later) and am removing all that have more than 2 divisors因此,我制作了一个数组,用 1 – 10 的所有数字填充它(稍后我会做 1000),并删除所有具有 2 个以上除数的数字
The issue:问题:
The code below seems to not be checking 5,7, or 9.下面的代码似乎没有检查 5,7 或 9。
My code (ruby)我的代码(红宝石)
#Create an array that will be your list of prime numbers
primes = []
#create variables
x = 1
counter = 0
y=1
#fill array with numbers (I'm using 10 rather than 1000 for now)
for x in 1..10 # 1..10 is inclusive in ruby
primes.push(x) #put x into primes array
end
primes.each do |prime_number| for y in 1..10 do #for each x and each y, do the following
puts "#{prime_number} , #{y}" #puts is print with a new line
if prime_number % y == 0 #check if element in array divided by numbers 1-10 is mod 0
counter +=1 #is so increase counter by 1
if counter > 2
primes.delete(prime_number)
counter = 0 #if counter get's above 2 then number cannot be prime. hence remove it from array
end
end
end
end
puts primes #print out primes to check result
sum_of_primes = primes.inject(:+) #sum of all primes
puts sum_of_primes #print answer
Here is output:这是输出:
1 , 1
1 , 2
1 , 3
1 , 4
1 , 5
1 , 6
1 , 7
1 , 8
1 , 9
1 , 10
2 , 1
2 , 2
2 , 3
2 , 4
2 , 5
2 , 6
2 , 7
2 , 8
2 , 9
2 , 10
4 , 1
4 , 2
4 , 3
4 , 4
4 , 5
4 , 6
4 , 7
4 , 8
4 , 9
4 , 10
6 , 1
6 , 2
6 , 3
6 , 4
6 , 5
6 , 6
6 , 7
6 , 8
6 , 9
6 , 10
8 , 1
8 , 2
8 , 3
8 , 4
8 , 5
8 , 6
8 , 7
8 , 8
8 , 9
8 , 10
10 , 1
10 , 2
10 , 3
10 , 4
10 , 5
10 , 6
10 , 7
10 , 8
10 , 9
10 , 10
[1, 3, 5, 7, 9]
25
You can refactor your iterators to avoid explicit loops and counters.您可以重构迭代器以避免显式循环和计数器。 Even though you're still iterating, leveraging core methods can be faster and easier to debug.
即使您仍在迭代,利用核心方法也可以更快、更容易地进行调试。
For completeness, I also provide an example using Ruby's Prime module from the standard library.为了完整起见,我还提供了一个使用标准库中 Ruby 的Prime模块的示例。 This is probably the most correct solution, but the use of the module is a solution that largely dodges the iteration question entirely, at least from a pragmatic point of view.
这可能是最正确的解决方案,但使用该模块是一种在很大程度上完全避免迭代问题的解决方案,至少从实用的角度来看是这样。
If your question is for schoolwork, then my answer may not help you learn whatever it is your instructor wants you to learn from the lesson.如果您的问题是关于功课,那么我的回答可能无法帮助您学习您的老师希望您从课程中学到的任何东西。 Other answers may explain why your current code doesn't work as intended;
其他答案可能会解释为什么您当前的代码无法按预期工作; I will instead focus on an alternate approaches that leverage more of Ruby's core capabilities.
相反,我将专注于利用更多 Ruby 核心功能的替代方法。
Here's one way to find all the positive primes up to a given maximum value:这是一种找到所有正素数直到给定最大值的方法:
# Use a Range object to check each Integer between 2 and
# (int - 1) to see if there's a remainder. If not, the value
# of i is added to the anonymous array returned by #map. The
# int is prime if there are no elements in the array.
def prime? int
(2...int).none? { |i| int.modulo(i).zero? }
end
# Iterate from 2 to the maximum value, using #select to
# return the subset of values passed to the block where the
# return value of #prime? is truthy.
#
# NB: 1 isn't prime, which is why we start from 2. Reference:
# <https://en.wikipedia.org/wiki/Prime_number#Primality_of_one>
def find_primes max_value
2.upto(max_value).select { |i| prime? i }
end
find_primes 10
#=> [2, 3, 5, 7]
There are certainly other ways to do this, but leveraging built-in iterators like Array#none?当然还有其他方法可以做到这一点,但是利用像Array#none这样的内置迭代器? and Array#select while avoiding counters seems like a net win to me.
和Array#select同时避免计数器对我来说似乎是一个净胜。 Your mileage may vary.
你的旅费可能会改变。
As a further simplification, you might simply use the Prime module from the Ruby standard library.作为进一步的简化,您可以简单地使用 Ruby 标准库中的Prime模块。 For example, Prime#each returns an enumerable Prime::EratosthenesGenerator .
例如, Prime#each返回一个可枚举的Prime::EratosthenesGenerator 。 You can then call Enumerable#to_a to convert the results to an Array.
然后,您可以调用Enumerable#to_a将结果转换为数组。 For example:
例如:
require 'prime'
def primes max_value
Prime.each(max_value).to_a
end
primes 10
#=> [2, 3, 5, 7]
Leveraging core and standard library classes is usually faster (and potentially less error-prone) than implementing your own routines, but this may be "a bridge too far" for educational purposes.利用核心和标准库类通常比实现自己的例程更快(并且可能更不容易出错),但这对于教育目的来说可能是“一座桥太远了”。 Nevertheless, I include it here for completeness and to help future visitors.
尽管如此,我将其包含在此处是为了完整性并帮助未来的访问者。
The code below seems to not be checking 5,7, or 9
下面的代码似乎没有检查 5,7 或 9
That's because you are deleting elements from the array while traversing it.那是因为您在遍历数组时从数组中删除元素。
As a workaround, you can traverse the array in reverse order using reverse_each
:作为一种解决方法,您可以使用
reverse_each
以相反的顺序遍历reverse_each
:
primes = (2..20).to_a
primes.reverse_each do |prime_number|
counter = 0
1.upto(20) do |y|
if prime_number % y == 0
counter += 1
primes.delete(prime_number) if counter > 2
end
end
end
primes
#=> [2, 3, 5, 7, 11, 13, 17, 19]
Or you could use delete_if
which deletes the current element in-place if the block evaluates to true
:或者您可以使用
delete_if
,如果块评估为true
,它会就地删除当前元素:
primes = (2..20).to_a
primes.delete_if do |prime_number|
counter = 0
(1..20).find do |y|
counter += 1 if prime_number % y == 0
counter > 2
end
end
primes
#=> [2, 3, 5, 7, 11, 13, 17, 19]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.