Definitions
A circular prime is a prime number with the property that the number generated at each intermediate step when cyclically permuting its (base 10) digits will also be prime.

For example:
1193 is a circular prime, since 1931, 9311 and 3119 are all also prime.

Note that a number which is a cyclic permutation of a smaller circular prime is not considered to be itself a circular prime. So 13 is a circular prime, but 31 is not.



A repunit (denoted by R) is a number whose base 10 representation contains only the digit 1.

For example:
R(2) = 11 and R(5) = 11111 are repunits.



Task
 Find the first 19 circular primes.


 If your language has access to arbitrary precision integer arithmetic, given that they are all repunits, find the next 4 circular primes.


 (Stretch) Determine which of the following repunits are probably circular primes: R(5003), R(9887), R(15073), R(25031), R(35317) and R(49081). The larger ones may take a long time to process so just do as many as you reasonably can.


See also
 Wikipedia article - Circular primes.
 Wikipedia article - Repunit.
 OEIS sequence A016114 - Circular primes.


require 'gmp'
require 'prime'
candidate_primes = Enumerator.new do |y|
  DIGS = [1,3,7,9]
  [2,3,5,7].each{|n| y << n.to_s}
  (2..).each do |size|
    DIGS.repeated_permutation(size) do |perm|
      y << perm.join if (perm == min_rotation(perm)) && GMP::Z(perm.join).probab_prime? > 0
    end
  end
end
 
def min_rotation(ar) = Array.new(ar.size){|n| ar.rotate(n)}.min
 
def circular?(num_str)
  chars = num_str.chars
  return GMP::Z(num_str).probab_prime? > 0 if chars.all?("1")
  chars.size.times.all? do 
   GMP::Z(chars.rotate!.join).probab_prime? > 0
   # chars.rotate!.join.to_i.prime?
  end
end
 
puts "First 19 circular primes:"
puts candidate_primes.lazy.select{|cand| circular?(cand)}.take(19).to_a.join(", "),""
puts "First 5 prime repunits:"
reps = Prime.each.lazy.select{|pr| circular?("1"*pr)}.take(5).to_a
puts  reps.map{|r| "R" + r.to_s}.join(", "), ""
[5003, 9887, 15073, 25031].each {|rep| puts "R#{rep} circular_prime ? #{circular?("1"*rep)}" }
 