The number 3797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3.
Find the sum of the only eleven primes that are both truncatable from left to right and right to left.
NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes.
def eratostenes(n)
sito = Array.new(n, true)
sito[0],sito[1],sito[2] = nil,nil,true
i = 3
while i <= n do
unless sito[i]==nil then
j = 2i
while j <= n
sito[j] = nil
j += i
end
end
i += 2
end
return [2] + (3…n).select{|i| sito[i] == true && i.odd?}
end
class Integer
def truncatable?
return false if self.to_s.length < 2 || ( self.to_s.length > 2 && self.to_s =~ ( /^[0,1,2,4,5,6,8][:digit:][0,1,2,4,5,6,8]$/ ) )
return (1…self.to_s.length).map do |n|
[self.to_s.slice(n-1,self.to_s.length).to_i, self.to_s.slice(0,n).to_i]
end.flatten.all? {|prime| [2,3,5,7].index(prime) || $sieve.index(prime)}
end
end
$sieve = eratostenes(1_000_000).slice(4,1_000_000)
list = []
$sieve.each do |prime|
break if list.size >= 11
print “#{prime}\r”
if prime.truncatable?
list << prime
puts list.last
end
end
require 'prime'
class Fixnum
alias :old_prime? :prime?
def prime?
self != 0 and self != 1 and self.old_prime?
end
def is_truncatable_prime?
k = self
loop do
k = k % (10**(k.to_s.size-1))
break if k == 0
return false unless k.prime?
end
k = self
loop do
k = k / 10
break if k == 0
return false unless k.prime?
end
return true
end
end
primes = Prime.each
t = []
loop do
n = primes.next
next if n < 10
t << n if n.is_truncatable_prime?
break t if t.size == 11
end
p t
p t.inject(:+)
Wyniki:
real 0m5.200s
user 0m2.564s
sys 0m0.008s
BTW. Może mi ktoś powiedzieć dlaczego standardowe prime? dla 0 i 1 zwraca true?