def pali(a):
    return str(a) == str(a)[::-1]

print('Biggest palindromic product of two three digit integers is %i, which is %i * %i.' % 
       max((a*b, a, b) for a in range(999, 100, -1) for b in range(a, 100000//a, -1) if pali(a*b)))
""" Output:
Biggest palindromic product of two three digit integers is 906609, which is 993 * 913.
"""

Specialties:
IT/Science/Contracts/Religious translation/interpreting FIN-ENG-FIN
Python programming

Well that just blew my mind.

Is it actually quicker to define the pali() function than it would be to just put that expression into the generator expression? EG

       max((a*b, a, b) for a in range(999, 100, -1) for b in range(a, 100000//a, -1) if str(a*b))==str(a*b)[::-1])

I ask because sometimes my list comprehensions get really crowded and I never think to do this.

Edited 4 Years Ago by hughesadam_87

It is faster by one function call penalty per iteration to not to use function, but function compensate it by making the code more readable. Your generator version is incorrect, you misplaced a ')':

max((a*b, a, b) for a in range(999, 100, -1) for b in range(a, 100000//a, -1) if str(a*b)==str(a*b)[::-1])

The optimized version with loop, even this above one liner is for me fast enough

def pali(a):
    return str(a) == str(a)[::-1]

m = (0,0,0)
for a in range(999, 100, -1):
    if m[-1] > a:
        #print('Breaking with a = %i' % a)
        break
    for b in range(a, 100000//a, -1):
        if pali(a*b):
            if a * b > m[0]:
                m = a*b, a, b
                #print m
            break


print('Biggest palindromic product of two three digit integers is %i, which is %i * %i.' % m)

""" Debug output:
(580085, 995, 583)
(906609, 993, 913)
Breaking with a = 912
Biggest palindromic product of two three digit integers is 906609, which is 993 * 913.
"""

Edited 4 Years Ago by pyTony

The article starter has earned a lot of community kudos, and such articles offer a bounty for quality replies.