This problem is a slightly harder version of Primey Palindromes .
Let
f
(
x
)
be the sum of the digits of
x
.
Let
g
(
n
)
be the number of
n
digit palindromes
a
such that
-
a
is prime,
-
a
+
f
(
a
)
is also prime.
What is the smallest value of n > 2 such that g ( n ) is not 0 and not prime?
Example
-
3
8
3
is a prime palindrome.
-
f
(
3
8
3
)
=
3
+
8
+
3
=
1
4
.
-
3
8
3
+
f
(
3
8
3
)
=
3
9
7
which is also prime.
This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try
refreshing the page, (b) enabling javascript if it is disabled on your browser and,
finally, (c)
loading the
non-javascript version of this page
. We're sorry about the hassle.
Seems to be fastest. Is it so?
For every integer N we can generate two unique palindromes. For example for N = a b c (where a , b , c are the base 10 digits of N ) there exists two unique palindromes a b c c b a and a b c b a . By iterating through all possible N we can generate all palindromes.
Since we are dealing with prime palindromes here,we only need to generate palindromes with odd number of digits(The second type a b c b a ). This is because all prime palindromes except 1 1 have an odd number of digits.
Using the method described above , we generate all such palindromes,test primality with Miller-Rabin,count them with a hashmap and print the first n such that g ( n ) is not prime.
Code in Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
|
This is because all prime palindromes except 11 have an odd number of digits.
Why is this true?
Log in to reply
The divisibility test for 11 is that if you add up every second digit then take away the rest, if you get 0 or a multiple of 11 then the number is divisible by 11. So when you have a palindrome with an even number of digits it will be of the form a b b a or a b c c b a or a b c d d c b a . . . e t c and in every case when you use that divisibility test you get 0. So for example using the cases above: b + a − ( a + b ) = 0 b + c + a − ( a + c + b ) = 0 b + d + c + a − ( a + c + d + b ) = 0 And this will work for all palindromes with an even number of digits, they are all divisible by 11 and therefore not prime. This of course works for 11 too but 11 is prime :)
meta question: How do you paste a code with formatting and all other stuff?
First build a sieve, then iterate over all palindromes
import math
primes = [2]
def is_prime(number):
# primes are always 1, 5 mod 6
if number % 6 not in (1, 5):
return False
if number in primes:
return True
for prime in primes:
if prime > math.sqrt(number):
return True
if number % prime == 0:
return False
return True
def gen_primes(top):
for candidate in range(2, top):
if is_prime(candidate):
primes.append(candidate)
gen_primes(100000)
assert is_prime(383)
assert is_prime(70607)
def sumdigits(number):
return sum(map(int, str(number)))
# each palindrome is made of a matching left and right
def palindrome_lefts(length):
start = 10 ** (length-1)
for x in xrange(start, 10 ** length):
yield str(x)
def even_palindromes(length):
assert length % 2 == 0
for left in palindrome_lefts(length/2):
yield left + ''.join(reversed(left))
def palindromes(length):
if length % 2 == 0:
for item in even_palindromes(length):
yield int(item)
return
for palindrome in even_palindromes(length-1):
for i in xrange(10):
mid = length/2
yield int(palindrome[:mid] + str(i) + palindrome[mid:])
def matches_in_n(length):
for item in palindromes(length):
if is_prime(item) and is_prime(item + sumdigits(item)):
yield item
for index, match in enumerate(matches_in_n(9)):
print index+1, match
print 'finished'
I used two codes (both written in Python), first is the code for Miller-Rabin Primality Test (used to check if number is prime):
#Filename: MillerRabin.py
import random
def decompose(n):
exponentOfTwo = 0
while n % 2 == 0:
n = n/2
exponentOfTwo += 1
return exponentOfTwo, n
def isWitness(possibleWitness, p, exponent, remainder):
possibleWitness = pow(possibleWitness, remainder, p)
if possibleWitness == 1 or possibleWitness == p - 1:
return False
for _ in range(exponent):
possibleWitness = pow(possibleWitness, 2, p)
if possibleWitness == p - 1:
return False
return True
def probablyPrime(p, accuracy=100):
if p == 2 or p == 3: return True
if p < 2: return False
numTries = 0
exponent, remainder = decompose(p - 1)
for _ in range(accuracy):
possibleWitness = random.randint(2, p - 2)
if isWitness(possibleWitness, p, exponent, remainder):
return False
return True
and the second is for the solution itself:
import MillerRabin as PrimalityTest #used for checking if number is prime
def sumOfDigits(num):
num = (str)(num)
sum = 0
for digit in num:
numberValue = (int)(digit)
sum += numberValue
return sum
def numOfNDigitPrimeyPalindromes(numDigits):
nDigitPalindromes = getNDigitPalindromes(numDigits)
numPrimeyPalindromes = 0
for num in nDigitPalindromes:
if isPrimey(num):
numPrimeyPalindromes += 1
return numPrimeyPalindromes
def getNDigitPalindromes(numDigits):
#Palindrome = leftNo + (midNo) + rightNo
#rightNo = mirrorString(leftNo)
nDigitPalindromes = []
digits = [0,1,2,3,4,5,6,7,8,9]
numDigitsLeftNo = numDigits/2
min = 10**(numDigitsLeftNo-1)
max = min*10
for leftNo in range (min,max):
if numDigits % 2 == 0:
palindrome = (str)(leftNo) + mirrorString(leftNo)
nDigitPalindromes.append((int)(palindrome))
else:
for digit in digits:
palindrome = (str)(leftNo) + (str)(digit) + mirrorString(leftNo)
nDigitPalindromes.append((int)(palindrome))
return nDigitPalindromes
def mirrorString(string):
string = (str)(string)
temp = ''
for character in string:
temp = character + temp
return temp
def isPrimey(num):
a = num
f = sumOfDigits(a)
return PrimalityTest.probablyPrime(a) and PrimalityTest.probablyPrime(a+f)
n = 3
while True:
g = numOfNDigitPrimeyPalindromes(n)
isPrime = PrimalityTest.probablyPrime(g)
print ''
print 'n:\t',n
print 'g(n):\t',g
print 'Prime:\t',isPrime
print ''
if g != 0 and not isPrime:
break
n += 1
this code is pretty slow though, it took around a minute to iterate and stop at n = 9
Total[Total[ Boole[PrimeQ[#] && PrimeQ[# + Total[IntegerDigits[#]]]] & /@ FromDigits /@ Table[Flatten[{IntegerDigits[#], i, Reverse[IntegerDigits[#]]}], {i, 0, 9}] & /@ Range[1001, 9999, 2]]]
Gives an output of 177 9 digit palindromes in 0.36seconds.
Problem Loading...
Note Loading...
Set Loading...
This code takes just 0.25 secs to list all the palindromic primes less than 10000000000 that satisfy the given constraints.