-5

A palindromic prime is a prime number that is also palindromic. For example, 131 is a prime and also a palindromic prime, as are 313 and 757.

I need to write a function that displays the first n palindromic prime numbers. Display 10 numbers per line and align the numbers properly, as follows:

2     3     5     7    11   101   131   151   181   191
313   353   373   383   727   757   787   797   919   929

my code is:

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

the code works but not in the way i wanted:

>>> paliPrime(10)
3
5
7
>>> 

And what I want is a function that displays the first n palindromic prime numbers. It should display 10 numbers per line and align the numbers properly.

Will Ness
  • 62,652
  • 8
  • 86
  • 167
Lucia
  • 35
  • 1
  • 7
  • 1
    Have you considered what your code is doing and why it isn't producing your desired output? What do you think `for I in range(a,b)` is doing if `b` is your input? – HavelTheGreat Jan 18 '16 at 11:04
  • 1
    @Lucia Your code works fine for finding palindromic primes. Your problem is that you are not checking how many palindromic primes you have found at any stage. Maybe that's a good place to start? – Rob Murray Jan 18 '16 at 11:19
  • Use an [indefinite primes generator](https://stackoverflow.com/questions/2211990/how-to-implement-an-efficient-infinite-generator-of-prime-numbers-in-python/10733621#10733621) and slap an itertools filter on top of it, to keep only palindromic primes, then use [`islice(filtered_primes,n)`](https://docs.python.org/3.5/library/itertools.html#itertools.islice) to get `n` first such primes. – Will Ness Jan 18 '16 at 11:57
  • @WillNess You should write that as an answer. – Reti43 Jan 18 '16 at 12:14
  • I would love to have answer from one of you @Reti43 or WillNess Good karma will be return :) – Lucia Jan 18 '16 at 12:30

2 Answers2

1

Use an indefinite primes generator and slap an itertools filter on top of it, to keep only palindromic primes, then use islice(filtered_primes,n) to get n first such primes:

from itertools import *

def palindPrimes(n):
    k = 0
    for p in islice( filterfalse( lambda x: str(x) != str(x)[::-1], 
                                  postponed_sieve()), n):
      ## adjust the alignment and print it, then
      k += 1
      if k == 10:
          k = 0
          ## print a newline to start a new line
Will Ness
  • 62,652
  • 8
  • 86
  • 167
1

WillNess showed you a really good way of doing (go with it). I'll show you what you did wrong with your way so you can learn from it.

Since you don't know the range of the first N prime palidromes, you want to iterate indefinitely and keep a count of those you have found. In simplified pseudocode.

count = 0
number = 2
while count < N
    if number is palidromic prime
        print number
        count += 1
    number += 1

With adding some bells and whistles in your code to print the numbers in the right format, you get

def paliPrime(n):
    fmt = '%-5d'
    if n >= 1:
        print fmt % 2,
    count = 2
    i = 3
    while count <= n:
        paliPrime=True
        if str(i) == str(i)[::-1]:
            for a in range(2,i):
                if i%a==0:
                    paliPrime=False
                    break
            if paliPrime:
                print fmt % i,
                if count%10 == 0:
                    print 
                count += 1
        i += 2
    # add a newline at the end if we haven't done so already
    if count%10 != 1:
        print

A bit of general advice is that you should keep each function to one responsibility. Here you both generate and print the numbers. Imagine if one day you wanted to reuse the code to generate these numbers so they could be silently used in your program. You'd be littered with prints everywhere.

Now, regarding the solution, you may have noticed is that I investigated numbers starting from 3 and in increments of 2. That's because you're guaranteed all even numbers, except from 2, to not be prime.

And here what WillNess showed you becomes relevant. There are much better algorithms to generate the next prime or check whether a number is prime instead of brute forcing trial division, which, by the way, you can limit up to sqrt(i).

Reti43
  • 8,010
  • 3
  • 22
  • 40
  • Just one question @Reti43 what fmt = '%-5d' means? i'm a beginner i'm sorry – Lucia Jan 18 '16 at 14:04
  • @Lucia It's string formatting. You can read more about it [here](https://pyformat.info/). Specifically, `'%5d' % 6` will print the number 6 aligned to the right and take up 5 spaces, so `' 6'`, while the minus in there will cause it to be left aligned: `'6 '`. – Reti43 Jan 18 '16 at 15:43
  • Thank you @Reti43, you helped me a lot :-) – Lucia Jan 18 '16 at 20:24