# return base ^ exp % mod
def modpow(base, exp, mod)
result = 1
while exp > 0
result = (result * base) % mod if exp & 1 == 1
exp >>= 1
base = base ** 2 % mod
end
result
end
# http://j...content-available-to-author-only...a.org/wiki/%E3%83%9F%E3%83%A9%E3%83%BC-%E3%83%A9%E3%83%93%E3%83%B3%E7%B4%A0%E6%95%B0%E5%88%A4%E5%AE%9A%E6%B3%95
def prime?(n)
return true if n == 2
return false if n == 1 || n & 1 == 0
d = n - 1
d >>= 1 while d & 1 == 0
20.times do
a = rand(n - 2) + 1
t = d
y = modpow(a, t, n)
while t != n - 1 && y != 1 && y != n - 1
y = y ** 2 % n
t <<= 1
end
return false if y != n - 1 && t & 1 == 0
end
true
end
def palinds_downto(bound)
return bound.downto(1) if bound < 10
sbound = bound.to_s
size = sbound.size
half_front = sbound[0, size / 2]
half_back = sbound[size / 2 + (size & 1), size]
odd_size = size % 2 == 1
pivot = odd_size ? sbound[size / 2].to_i : 9
Enumerator.new do |y|
init = half_front.to_i
lower_bound = 10 ** (half_front.size - 1)
if half_back.to_i > half_front.reverse.to_i
if odd_size
y << "#{half_front}#{pivot}#{half_front.to_s.reverse}".to_i
pivot -= 1
end
else
init -= 1
end
while init > 0
if odd_size
init.downto(lower_bound) do |n|
s = n.to_s
pivot.downto(0).each {|p| y << "#{s}#{p}#{s.reverse}".to_i }
pivot = 9
end
odd_size = false
init = lower_bound * 10 - 1
else
init.downto(lower_bound) do |n|
s = n.to_s
y << (s + s.reverse).to_i
end
odd_size = true
init = lower_bound - 1
lower_bound /= 10
end
end
9.downto(1) {|i| y << i }
end
end
puts palinds_downto(2 ** 80).find {|i| prime?(i) }
puts palinds_downto(2 ** 30).find {|i| prime?(i) }