Question

So I'm trying to figure out how to find all the palindrome prime numbers between 2 numbers. So far my code can find the palindrome but when I check for a prime number, it prints out the non-primes as well. And there are numbers which are printed multiple times.

Could you please help.

Thanks.

a = 0
b = 500
a += 1   
for i in range(a,b):
    if(str(i) == str(i)[::-1]):
        if(i>2):
            for a in range(2,i):
                y = True
                if(i%a==0):
                    y = False
                    break
            if y:
                print(i)
Was it helpful?

Solution

Based on your most recent code, you simply need to make sure that you reset y, which serves as your positive indicator of primality, for each number you test. Otherwise, it will stay False when you get to the number 4, the first composite number.

>>> a = 0
>>> b = 500
>>> a += 1
>>> for i in range(a,b):
        y = True
        if(str(i) == str(i)[::-1]):
            if(i>2):
                for a in range(2,i):
                    if(i%a==0):
                        y = False
                        break
                if y:
                    print(i)


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

As you can see, all of these are prime. You can check the list of primes wolframalpha provides to be sure that no palindromic primes have been omitted. If you want to include 2, add a special case for that.

OTHER TIPS

Please see my comments below:

a = 0
b = 500
a += 1
y = True
for i in range(a,b):
    if(str(i) == str(i)[::-1]):
        print (i)      # <--- You print every number that is a palindrome
        if(i>2):
            for a in range(2,i):
                if(i%a==0):
                    y = False   # <--- This never gets set back to True
                    break
            if y:
                print(i)

        i+=i   # <--- This is doing nothing useful, because it's a "for" loop

Look at my code below, we don't need to initialize Y as well. A For-Else block works well.

a = 0
b = 500
a += 1
for i in range(a,b):
    if(str(i) == str(i)[::-1]):
        if(i>1):
            for a in range(2,i):
                if(i%a==0):
                    y = False
                    break
            else:
                print(i)

To get 2 included in the answer, just be sure to check the if condition as (i>1) as mentioned by @elias

Here is the pretty fast implementation based on "Sieve of Atkin" algorithm. I calculate all primes numbers up to the end and then filter only palindromic ones where number is greater or equal to start.

import math
import sys

def pal_primes(start,end):
    return list(filter(lambda x: str(x)==str(x)[::-1] and x>=start, sieveOfAtkin(end)))
    
    def sieveOfAtkin(limit):
        P = [1,2,3]
        sql = int(math.sqrt(limit))
        r = range(1,sql+1)
        sieve=[False]*(limit+1)
        for x in r:
            for y in r:
                xx=x*x
                yy=y*y
                xx3 = 3*xx
                n = 4*xx + yy
                if n<=limit and (n%12==1 or n%12==5) : sieve[n] = not sieve[n]
                n = xx3 + yy
                if n<=limit and n%12==7 : sieve[n] = not sieve[n]
                n = xx3 - yy
                if x>y and n<=limit and n%12==11 : sieve[n] = not sieve[n]
        for x in range(5,sql):
            if sieve[x]:
                xx=x*x
                for y in range(xx,limit+1,xx):
                    sieve[y] = False
        for p in range(5,limit):
            if sieve[p] : P.append(p)       
        return P
    
    
    if __name__=="__main__":
        print(pal_primes(int(sys.argv[1]),int(sys.argv[2])))

Based on this thread:

Sieve Of Atkin Implementation in Python

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top