Ruby 编写输出前100个回文素数的脚本时出现问题

Ruby 编写输出前100个回文素数的脚本时出现问题,ruby,Ruby,我写这个脚本是为了找到前100个同样是回文的素数。由于某些原因,一些素数没有打印出来(13、17等),回文函数似乎不起作用。有什么建议吗 #palindrome checker def is_palindrome?(number) number == number.to_s.reverse.to_i end #primes will consists of all primes starting with 2 #i will be incrememented and each i w

我写这个脚本是为了找到前100个同样是回文的素数。由于某些原因,一些素数没有打印出来(13、17等),回文函数似乎不起作用。有什么建议吗

#palindrome checker
def is_palindrome?(number)
    number == number.to_s.reverse.to_i
end


#primes will consists of all primes starting with 2
#i will be incrememented and each i will be checked for being prime
primes = [2]
i = 3

#we only want the first 100 palindromic primes
while primes.length < 100
    #test is false for a prime
    test = false
    #checks if i is divisible by any of the elements in the array
    primes.each { |n| 
        if i % n == 0
            test = true
        end
    }
    #if i is prime that it is added to the primes array
    if test == false
        primes.push(i)
    end
    i += 1
end

#remove all non palindromic primes 
primes.each { |n|
    if is_palindrome?(n) == false
        primes.delete(n)
    end
}

#puts palindromic primes
puts primes
#回文检查器
def是_回文?(数字)
number==number.to_.s.reverse.to_.i
结束
#素数将包括从2开始的所有素数
#我将被递增,每个我都将被检查为素数
素数=[2]
i=3
#我们只需要前100个回文素数
而primes.length<100
#测试对于素数是错误的
测试=错误
#检查i是否可被数组中的任何元素整除
素数
如果i%n==0
测试=真
结束
}
#如果我是素数,它将被添加到素数数组中
如果测试=false
素数推(i)
结束
i+=1
结束
#删除所有非回文素数
素数|
如果是回文?(n)=假
素数。删除(n)
结束
}
#放置回文素数
放置素数

我不确定内部工作,但是从正在迭代的数组中删除元素会导致它跳过一些内容。例如:

>> arr = %w{John Paul George Ringo}
=> ["John", "Paul", "George", "Ringo"]
>> # Print each one out; delete if it contains "o"
>> arr.each {|e| puts e; arr.delete e if e =~ /o/}
John
George
=> ["Paul", "Ringo"]
甚至没有对Paul或Ringo进行评估

你应使用:

但是,更具体地说,对于您的问题,您可以将
是回文吗?
检查用于构建数组的循环,从而消除第二个筛选循环的需要(并允许您构建所需的100个回文素数的列表)。

您的问题在于:

primes.each { |n|
    if is_palindrome?(n) == false
        primes.delete(n)
    end
}
您正在迭代
素数
,并在块内修改它。这很容易出错

试着做:

primes.each { |n|
    if is_palindrome?(n)
      puts n
    end
}

此外,您可以更好地编写代码,使其更具可读性,还可以使用更高效的算法来计算素数,如。

您的代码需要一些TLC。我是这样做的:

#palindrome checker
def is_palindrome?(number)
  number == number.to_s.reverse.to_i
end


#primes will consists of all primes starting with 2
#i will be incrememented and each i will be checked for being prime
primes = [2]
i = 3

#we only want the first 100 palindromic primes
while primes.length < 100

  #checks if i is divisible by any of the elements in the array
  primes << i unless primes.any? { |n| i % n == 0 }

  i += 1
end

#remove all non palindromic primes
primes.delete_if { |n| is_palindrome?(n) == false }

#puts palindromic primes
puts primes
primes.delete_如果{n|是回文?(n)=false}
可以更简洁地写成:

primes.delete_if { |n| !is_palindrome?(n) }
或者,取消剥离
素数
和调用
是回文?
并使用简单的
拒绝

puts primes.select{ |n| n == n.to_s.reverse.to_i }
这将代码简化为:

#primes will consists of all primes starting with 2
#i will be incrememented and each i will be checked for being prime
primes = [2]
i = 3

#we only want the first 100 palindromic primes
while primes.length < 100

  #checks if i is divisible by any of the elements in the array
  primes << i unless primes.any? { |n| i % n == 0 }

  i += 1
end

#puts palindromic primes
puts primes.select{ |n| n == n.to_s.reverse.to_i }
#素数将由以2开头的所有素数组成
#我将被递增,每个我都将被检查为素数
素数=[2]
i=3
#我们只需要前100个回文素数
而primes.length<100
#检查i是否可被数组中的任何元素整除

primes我将您的脚本更改为:

#palindrome checker
def is_palindrome?(number)
    number == number.to_s.reverse.to_i
end


#primes will consists of all primes starting with 2
#i will be incrememented and each i will be checked for being prime
primes = [2]
i = 3

#we only want the first 100 palindromic primes
while primes.length < 100
    #test is false for a prime
    test = false
    #checks if i is divisible by any of the elements in the array
    primes.each { |n| 
        if i % n == 0
            test = true
        end
    }
    #if i is prime that it is added to the primes array
    if test == false
        primes.push(i) if is_palindrome?(i) # This is the line I changed
    end
    i += 1
end


#puts palindromic primes
puts primes
#回文检查器
def是_回文?(数字)
number==number.to_.s.reverse.to_.i
结束
#素数将包括从2开始的所有素数
#我将被递增,每个我都将被检查为素数
素数=[2]
i=3
#我们只需要前100个回文素数
而primes.length<100
#测试对于素数是错误的
测试=错误
#检查i是否可被数组中的任何元素整除
素数
如果i%n==0
测试=真
结束
}
#如果我是素数,它将被添加到素数数组中
如果测试=false
primes.push(i)if_回文?(i)#这是我更改的行
结束
i+=1
结束
#放置回文素数
放置素数

通过同时修改和迭代
primes
数组,您得到了奇怪的错误。我把回文检查移到了while循环中,所以你会得到100个回文,而不是100个素数减去非回文

我是这样写的:

require 'prime'

is_palindrome = -> i { i.to_s == i.to_s.reverse }
puts Prime.lazy.select(&is_palindrome).take(100).to_a
简单、清晰、简洁

输出为:

# 2
# 3
# 5
# 7
# 11
# 101
# 131
# 151
# 181
# 191
# 313
# 353
# 373
# 383
# 727
# 757
# 787
# 797
# 919
# 929
# 10301
# 10501
# 10601
# 11311
# 11411
# 12421
# 12721
# 12821
# 13331
# 13831
# 13931
# 14341
# 14741
# 15451
# 15551
# 16061
# 16361
# 16561
# 16661
# 17471
# 17971
# 18181
# 18481
# 19391
# 19891
# 19991
# 30103
# 30203
# 30403
# 30703
# 30803
# 31013
# 31513
# 32323
# 32423
# 33533
# 34543
# 34843
# 35053
# 35153
# 35353
# 35753
# 36263
# 36563
# 37273
# 37573
# 38083
# 38183
# 38783
# 39293
# 70207
# 70507
# 70607
# 71317
# 71917
# 72227
# 72727
# 73037
# 73237
# 73637
# 74047
# 74747
# 75557
# 76367
# 76667
# 77377
# 77477
# 77977
# 78487
# 78787
# 78887
# 79397
# 79697
# 79997
# 90709
# 91019
# 93139
# 93239
# 93739
# 94049

下面是Ruby素数生成器的另一个用途:

require 'prime'

e = Prime.each
100.times {begin i = e.next end until i.to_s == i.to_s.reverse; puts i}

2
3
5
7
11
101
131
151
181
191
313
353
373
383
727
... 
下面是一个质数生成器,它响应
next

e.class = Prime::EratosthenesGenerator
或者

i = e.succ

这一行代码将给出前100个回文素数的数组

require 'prime' 
p Prime.each.lazy.select{|x| x.to_s == x.to_s.reverse}.first(100)

以下是我编写解决方案的方式:

require 'prime'

def palindrome?(number)
  number == number.reverse
end

def palindrome_prime(n)   
  final = []
  num =2
  while(num)
    if (Prime.prime?(num) && palindrome?(num.to_s))
      final.push(num)
      if (final.length == n)
        print final
        return final
      end
    end
    num += 1
  end   
end

p palindrome_prime(100)

这里的一些有组织的代码也处理性能问题。更具可读性和可重用性。可能会帮助别人

检查素数的方法 def是_素数?(n) 2.最多(n/2)。每个do | x| 如果n%x==0,则返回false 结束 真的 结束

使用递归检查给定字符串是否为回文的方法。 def是回文记录吗?(str) 如果str.length==0 | | str.length==1,则返回true 如果(str[0]!=str[-1])返回false 返回是回文记录?(str[1..-2]) 结束

使用延迟加载返回回文素数的方法。它首先作用于N个回文素数。 def回文素数(n) 2.upto(Float::INFINITY).lazy.map{| x | 如果(is|u prime?(x)和&is|u回文_rec?(x.to|u s))}。选择{x | x.is|a? 整数}.first(n) 结束

#在此处传递N作为参数。你的情况是100英镑。
结果=s.回文素数(25)
打印结果


#输出-->[2、3、5、7、11、101、131、151、181、191、313、353、373、383、727、757、787、797、919、929、10301、10501、10601、11311、11411]
它以什么方式似乎不起作用?为什么它要打印那些素数(不是回文)?此外,它看起来会得到前100个素数,然后删除那些不是回文的素数(列表中的素数少于100个)。这不起作用,因为其中包含了很多不是回文的素数。第二部分你说得对,我在提交问题后注意到@iamnotmaynardNice使用
惰性
,Jörg+1我在这里学到的美丽的东西<代码>执行并选择惰性地协同工作。您可以删除
开始..结束
。。需要吗?我不这么认为
i=e.next直到i.to_s==i.to_s.reverse
正常。问题是必须首先执行
i=e.next
。试试看。我想进一步简化一下。然后把一行
I=e.next
放在,
#times
之前。那就不需要开始了。结束了。我考虑过了,但没有
is_palindrome = -> (i) { i.to_s == i.to_s.reverse }

def prime?(number)
  flag = true

  (2..number/2).each do |n|
    if (number%n) == 0
      flag = false
      break
    end
  end

 flag
end

palindromic_primes = -> (length) do 
  2.upto(Float::INFINITY).lazy.select { |x| is_palindrome.call(x) && prime?(x)  }.first(length)
end

puts palindromic_primes.(5)
require 'prime' 
p Prime.each.lazy.select{|x| x.to_s == x.to_s.reverse}.first(100)
require 'prime'

def palindrome?(number)
  number == number.reverse
end

def palindrome_prime(n)   
  final = []
  num =2
  while(num)
    if (Prime.prime?(num) && palindrome?(num.to_s))
      final.push(num)
      if (final.length == n)
        print final
        return final
      end
    end
    num += 1
  end   
end

p palindrome_prime(100)