views:

186

answers:

6

I'm again working on Project Euler, this time problem #4. The point of this script is to find the largest palindromic product of two three digit numbers. I thought it was fairly straightforward to solve, but I'm getting an answer that is too low. More specifically, I am getting 580085, and the answer is 906609.

Could someone tell me what about this is incorrect?

#!/usr/bin/env python
# encoding: utf-8
"""
P4.py

Created by Andrew Levenson on 2010-06-29.
Copyright (c) 2010 __MyCompanyName__. All rights reserved.
"""

import sys
import os


def main():
    for x in range(100, 1000):
        for y in range(100, 1000):
            z = str( x * y )
            s = str( z[::-1] ) # Reverse z
            if z == s:
                t = z
    print t


if __name__ == '__main__':
    main()
+6  A: 

Your code doesn't make sure it prints the largest product, since there could later be a smaller product which replaces it. To fix it, initialize t to zero, and replace your condition with

if z==s and int(z)>t:
    t = int(z)

Or equivalently,

if z==s:
    t = max(t,int(z))

Edit: Fixed int/string issues above. It's a bit cleaner to avoid the conversion to string and back to int like this though:

def isPalindrome(x):
    s = str(x)
    return s == s[::-1]

t = 0
for x in range(100, 1000):
    for y in range(100, 1000):
        z = x * y
        if isPalindrome(z) and z > t:
            t = z
print t
interjay
These edits aren't quite right: z is a string, not an int.
Ned Batchelder
You need to compare them as numbers, not as strings.
Florian Diesch
I'm working on figuring out why, but introducing your fixes yields the output `99999`
Andrew
Okay, so changing it to:` if z==s: if int(z) > int(t):...` fixes the issue. Thank you!
Andrew
Weird to keep changing ints to strings and back all the time... I prefer the "no going back" solution in my answer;-).
Alex Martelli
+3  A: 

The problem is to find the largest palindrome. You have nothing here to find the largest, simply the last. You assumed the last one would be the largest, but that isn't so because you are examining the entire ZxZ square of possibilities.

For example, you are considering 200*101 after you've considered 101*999.

Ned Batchelder
+1  A: 

You need to add a check if the one you found is larger than the one you already have.

Florian Diesch
+1  A: 

Because of the way you're using the 2 for loops you're going to get the number with the largest x value, not the largest product.

906609 = 993 * 913

Then x keeps incrementing and the next palindrome is:

580085 = 995 * 583

You need a variable to keep track of the largest palindrome you've found.

def main():
    largest = 0
    for x in range(100, 1000):
        for y in range(100, 1000):
            z = str( x * y )
            s = str( z[::-1] ) # Reverse z
            if z == s:
                t = int(z)
                if t > largest:
                    largest = t
    print largest
John
+5  A: 

Here's a tricky but correct way to do it in a single expression...:

def main():
  print max(p for x in range(100, 1000) for y in range(x, 1000)
              for p in (x * y,) if str(p) == str(p)[::-1])

The tricky part is the single-item for p clause which plays the role of an assignment (just to stop recomputing that product several times;-).

Note that the accepted answer is wrong (as are several others), because it looks for the string "max", which is different from the int max -- try running it, and you'll see!-)

Alex Martelli
That's pretty neat! Though were I newer to programming, that'd be a hell of an obfu.
Andrew
@Andrew, maybe -- and maybe not: I've seen people _totally_ new to programming take to list comprehensions (and genexps like the above one aren't too different, I just never taught total newbies since genexps were introduced so I have no direct experience with that) *much* more easily than, e.g., true mysteries such as `x = x + 1` ("but **how** can `x` possibly equal itself plus one?! No number does!")...;-). Kind-of-high-abstraction coding takes work to get there from (say) C, but not necessarily more, maybe less, than low-level stuff, to get there from "absolute zero".
Alex Martelli
A: 

I'll add that you can save yourself some time in this test. All 6 digit palindromes must be divisible by 11. Therefore at least one of the factors must be divisible by 11.

woodchips