Ruby - 使用惰性求值找到第一个 N 回文素数



我认为我的代码是正确的 - 但我没有及时返回 N = 200 的数组。错误为"因超时而终止" 我可以做些什么来提高此代码的性能?

def is_palindrome? (n)
n.to_s==n.to_s.reverse
end
def is_prime? (n)
return false if n< 2
(2..Math.sqrt(n)).none? {|f| n % f == 0}
end
prime_palindrome =-> (n) do
1.upto(Float::INFINITY).lazy.select { |n| is_prime?(n) && is_palindrome(n) }.first(n)
end

n = gets.to_i 
p prime_palindrome.call(n)

Ruby 知道如何更快地做到这一点。

require 'prime'
Prime.each.lazy.
select { |p| p.to_s.then { |s| s == s.reverse } }.
take(200).to_a

> 懒惰的枚举器(如@Amadan的答案中使用的(很有用,但似乎以速度慢而闻名。我认为在这里做一个简单的基准测试可能会很有趣,将 Amaman 的答案与使用while循环的简单计算进行比较。

require 'prime'

惰性枚举器

def amadan(n)
Prime::EratosthenesSieve.instance.send(:initialize)       
Prime.each.lazy.
select { |p| p.to_s.then { |s| s == s.reverse } }.
take(n).to_a
end

而循环

def cary(n)
Prime::EratosthenesSieve.instance.send(:initialize)
arr = []
enum = Prime.each
while n > 0
p = enum.next
s = p.to_s
if s == s.reverse
arr << p
n -= 1
end
end
arr
end

包括每个方法的第一行,Prime::EratosthenesSieve...以使基准更加真实。请参阅评论中的讨论。

基准

require 'fruity'

#

n = 200
compare(amadan: -> { amadan(n) }, cary: -> { cary(n) })
Running each test once. Test will take about 10 seconds.
cary is faster than amadan by 10.000000000000009% ± 1.0%
Results are similar for other values of `n`.

最新更新