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

时间:2014-02-12 23:13:50

标签: 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 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

10 个答案:

答案 0 :(得分:6)

以下是我写的方式:

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

答案 1 :(得分:1)

我不确定内部工作方式,但是从正在迭代的数组中删除元素会导致它跳过事情。 E.g:

>> 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"]

甚至没有评估PaulRingo

您应该使用Array#delete_if

primes.delete_if { |n| !is_palindrome?(n) }

但是,更具体地说,你的问题,你可以把is_palindrome?检查放在构建你的数组的循环中,不需要第二个过滤循环(并允许你建立100个回文列表)你想要的素数。)

答案 2 :(得分:1)

你的问题在这里:

primes.each { |n|
    if is_palindrome?(n) == false
        primes.delete(n)
    end
}

您正在迭代primes,并在块内修改它。这很容易出错。

尝试做:

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

此外,您可以更好地编写代码,使其更具可读性,并且您可以使用更有效的算法来计算素数,例如Sieve of Eratosthenes

答案 3 :(得分:1)

我通过将脚本更改为此来实现它:

#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

通过同时修改和迭代primes数组,您得到了奇怪的错误。我将回文检查移到了while循环内部,这样你实际上可以获得100个回文,相对于100个质数减去非回文。

答案 4 :(得分:0)

您的代码需要一些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

运行时输出:

# >> 2
# >> 3
# >> 5
# >> 7
# >> 11
# >> 101
# >> 131
# >> 151
# >> 181
# >> 191
# >> 313
# >> 353
# >> 373
# >> 383

primes.delete_if { |n| is_palindrome?(n) == false }可以更简洁地写成:

primes.delete_if { |n| !is_palindrome?(n) }

或者,取消摘录primes并致电is_palindrome?并使用简单的reject

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 }

答案 5 :(得分:0)

这是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
... 

此处Prime#each是响应next的素数生成器:

e.class = Prime::EratosthenesGenerator

可替换地,

i = e.succ

答案 6 :(得分:0)

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)

答案 7 :(得分:0)

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

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

答案 8 :(得分:0)

这是我编写解决方案的方式:

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)

答案 9 :(得分:0)

此处的一些有组织的代码也解决了性能问题。更具可读性和可重用性。可能会帮助某人。

for (int i = userChoice; i != 0; --i) { std::cout << i << std::endl; }

#method to check prime number def is_prime?(n) 2.upto(n/2).each do |x| return false if n % x == 0 end true end

# Method to Check if given string is palindrome using recursion. def is_palindrome_rec?(str) return true if str.length == 0 || str.length == 1 return false if (str[0] != str[-1]) return is_palindrome_rec?(str[1..-2]) end

# Method to return palindromic primes using lazy load. It works first N palindromic primes. def palindromic_primes(n) 2.upto(Float::INFINITY).lazy.map { |x| x if (is_prime?(x) && is_palindrome_rec?(x.to_s)) }.select { |x| x.is_a? Integer}.first(n) end

#Pass N here as parameter. In your case it will be 100. result = s.palindromic_primes(25) print result