S.L
S.L

Reputation: 183

Reversing a converted string in python

I would like to find the largest palindromic product of 2 3-digit numbers. This is my code:

for i in range(100,1000):
    for x in range(100,1000):
        number = i*x 
        number = str(number)
    if number==number[::-1]:
        print(number)
print("DONE")

It is doing nothing and just printing Done. I have converted the number to a string and done the slice thing but not working... just printing Done . How do I fix this?

EDIT

I wanted to make the palindromes go in a list and sort them in order of how big they are.

mylist=[]
for i in range(999,99,-1):
    for x in range(999, i-1, -1,):
        number=i*x
        number=str(number)
        if number==number[::-1]:
            print(number)
            mylist.append(number)
mylist=sorted(mylist)
print("DONE")
for i in mylist:
    for x in mylist:
        if int(i) <= int(x):
            mylist.pop(int(i))
            if x<= i:
                mylist.pop(int(x))

But still its not working... How to fix?

Upvotes: 0

Views: 82

Answers (3)

Michael
Michael

Reputation: 360

About code

You shoud check EVERY number, so your if statement should be inside a loop.

That's all about code.

Performance

For faster checking you may check from LARGEST number, and then go downwards.

Example: for i in range(999, 99, -1).

U used 999 here because left side is INCLUSIVE, but right threshold is NOT.

Next step is to optimize inner loop. You don't need to check each value. Just loop from 999 to i for optimal checking.

With this alghoritm your code will find largest palindromic number without checking iversive x and i order.

In your code it may check 30/70, then 70/30 for example

Fixed code

for i in range(999, 99, -1):
  for x in range(999, i - 1, -1):
    number = str(x * i)
    if number == number[::-1]:
      print(number)
print('Done!')

-1 in range is step. So negative step it's going downwards to 2nd number

Upvotes: 3

dawg
dawg

Reputation: 103694

I assume you are working on Problem 4 of Project Euler

You can use max:

>>> max((i*j,i,j) for i in range(999,99,-1) for j in range(999,i-1,-1) if str(i*j)==str(i*j)[::-1])
(906609, 913, 993)

That works in this case because the sheer number of elements is not that great for a modern computer.

But a cooler way to do this is to generate these numbers one by one from largest to smallest. Then the max is just the first one:

def factors(n):    
    ''' function to return the factors of a number '''
    return set(reduce(list.__add__, 
            ([i, n//i] for i in range(1, int(n**0.5) + 1) if n % i == 0)))

def pals(n, stop_n=0, length=3):
    ''' Generator to produce palindromes from largest to smallest '''
    while n>stop_n:
        if str(n)==str(n)[::-1]:
            for f1 in factors(n):
                f2=n//f1
                if len(str(int(f1)))==length and len(str(int(f2)))==length:
                    yield n, f1, f2     
        n-=1        


>>> next(pals(999*999))
(906609, 993, 913)

And can be used for larger numbers easily (knowing that larger numbers can take a long time but monumentally faster than generating all of them):

>>> next(pals(99999*99999,length=5))
(9966006699, 99979, 99681)
>>> next(pals(999999*999999,length=6))
(999000000999, 999999, 999001)

Upvotes: 1

greedy52
greedy52

Reputation: 1405

The if statement should be inside the inner for loop.

for i in range(100,1000):
    for x in range(100,1000):
        number = i*x
        number = str(number)
        if number==number[::-1]:
            print(number)
print("DONE")

Upvotes: 0

Related Questions