1
\$\begingroup\$

I am trying to identify and print pairs of 4 digit palindromes that sum up to a 5 digit palindrome.

This is what I have so far

def isPalindrome(x):
 return str(x)==str(x)[::-1]
palindrome = [x for x in range(1000, 10000) if isPalindrome(x)]
for x in palindrome:
 for y in palindrome:
 if (9999 < x+y < 100000) and isPalindrome(x+y):
 print(x, y, x+y)

I am estimating the time complexity for this to be O(n^2),because I am traversing the list twice. Is it possible to improve on this?

asked Feb 21, 2020 at 20:01
\$\endgroup\$
2
  • \$\begingroup\$ Welcome to code review where we review working code and provide tips on how to improve that code. Is this code working as expected? When you say This is what I have so far it indicates that the code is not complete and therefore off-topic. \$\endgroup\$ Commented Feb 22, 2020 at 16:38
  • \$\begingroup\$ The code is functional. But I don't think it is as efficient as it could be. \$\endgroup\$ Commented Feb 22, 2020 at 16:52

2 Answers 2

3
\$\begingroup\$

Two opportunities for optimization that suggest themselves to me:

  1. Seems like you should be able to produce an exhaustive list of 4-digit palindromes by taking every 2-digit number and then appending its mirror to it, rather than having to iterate through every 4-digit number and throw most of them out. That would let you build your palindrome list in about one-hundredth the time (you'll be iterating over 90 two-digit numbers instead of 9000 four-digit numbers in that first loop).

  2. A lot of the sums you're checking will be too small (i.e. they'll be 4 digits); none will be too big (9999+9999=19998). You can minimize the work you do on those sums by iterating from largest to smallest and breaking the inner loop once the sum gets too small.

An alternative to the nested for loops would be using one of the itertools functions to generate all the combinations as a set of tuples, but I don't think that'd get you any performance wins.

answered Feb 21, 2020 at 21:03
\$\endgroup\$
5
  • 1
    \$\begingroup\$ so something like palindrome = [int(str(x)+str(x)[::-1] for x in range(10,99)] to generate the list of palindromes. \$\endgroup\$ Commented Feb 21, 2020 at 21:13
  • \$\begingroup\$ range(10,100) I think, but yarp \$\endgroup\$ Commented Feb 21, 2020 at 21:23
  • \$\begingroup\$ For replacing nested for loops, i tried it with iter = itertools.combinations_with_replacement(palindrome, 2) but looping through itfor x,y in iter: I get half the number of results as before. Am I missing something? \$\endgroup\$ Commented Feb 21, 2020 at 21:26
  • \$\begingroup\$ Are the ones you're missing flipped versions of ones you already have? \$\endgroup\$ Commented Feb 21, 2020 at 23:42
  • \$\begingroup\$ That's possibly what's happening. Thank you for pointing me in the right direction \$\endgroup\$ Commented Feb 22, 2020 at 16:51
3
\$\begingroup\$

Instead of using the isPalindrome function to determine if x + y is a length five palindrome, you can create the set of all length five palindromes in the range [10000, 20000) and check for set membership instead. Use the efficient method suggested by Sam Stafford to generate them.

This does not change the time complexity, but should be faster.

answered Feb 23, 2020 at 15:06
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.