8

In problem 4 from http://projecteuler.net/ it says:

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 * 99.

Find the largest palindrome made from the product of two 3-digit numbers.

I have this code here

def isPalindrome(num):
    return str(num) == str(num)[::-1]
def largest(bot, top):
    for x in range(top, bot, -1):
        for y in range(top,bot, -1):
            if isPalindrome(x*y):
                return x*y
print largest(100,999)

It should find the largest palindrome, it spits out 580085 which I believe to be correct, but project euler doesn't think so, do I have something wrong here?


When I revered the for loop I didn't think it through, I removed the thing that checks for the biggest, silly me. Heres the working code

def isPalindrome(num):
    return str(num) == str(num)[::-1]
def largest(bot, top):
    z = 0
    for x in range(top, bot, -1):
        for y in range(top,bot, -1):
            if isPalindrome(x*y):
                if x*y > z:
                    z = x*y
    return z
print largest(100,999)

it spits out 906609

Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
FabianCook
  • 20,269
  • 16
  • 67
  • 115

14 Answers14

10

Iterating in reverse doesn't find the largest x*y, it finds the palindrome with the largest x. There's a larger answer than 580085; it has a smaller x but a larger y.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
5

This would more efficiently be written as:

from itertools import product

def is_palindrome(num):
    return str(num) == str(num)[::-1]

multiples = ( (a, b) for a, b in product(xrange(100,999), repeat=2) if is_palindrome(a*b) )
print max(multiples, key=lambda (a,b): a*b)
# (913, 993)

You'll find itertools and generators very useful if you're doing Euler in Python.

Jon Clements
  • 138,671
  • 33
  • 247
  • 280
  • Im only using python for this because it is an interpreted language, otherwise I would use java – FabianCook Oct 01 '12 at 13:50
  • @SmartLemon fair enough - Haskell's very useful as well though ;) – Jon Clements Oct 01 '12 at 13:50
  • @SmartLemon For these kind of things - definitely - look at the haskell solutions on the Euler answer board for the ones you've already solved - you'll find code snippet (I think there's also a website which has the code written for the first 'n' many problems in Haskell as well) – Jon Clements Oct 01 '12 at 13:54
2

Not the most efficient answer but I do like that it's compact enough to fit on one line.

print max(i*j for i in xrange(1,1000) for j in xrange(1,1000) if str(i*j) == str(i*j)[::-1])
user3833942
  • 125
  • 1
  • 6
1

Tried making it more efficient, while keeping it legible:

def is_palindrome(num):
    return str(num) == str(num)[::-1]

def fn(n):
    max_palindrome = 1
    for x in range(n,1,-1):
        for y in range(n,x-1,-1):
            if is_palindrome(x*y) and x*y > max_palindrome:
                max_palindrome = x*y
            elif x * y < max_palindrome:
                break
    return max_palindrome

print fn(999)
blueberryfields
  • 45,910
  • 28
  • 89
  • 168
0

Here I added two 'break' to improve the speed of this program.

def is_palindrome(num):
    return str(num) == str(num)[::-1]
def max_palindrome(n):
    max_palindrome = 1
    for i in range(10**n-1,10**(n-1)-1,-1):
        for j in range(10**n-1,i-1,-1):
            if is_palindrome(i*j) and i*j > max_palindrome:
                max_palindrome = i * j
                break
            elif i*j < max_palindrome:
                break
    return max_palindrome
n=int(raw_input())
print max_palindrome(n)
CooLee
  • 101
  • 2
0

Simple:

def is_pallindrome(n):
    s = str(n)
    for n in xrange(1, len(s)/2 + 1):
        if s[n-1] != s[-n]:
            return False    
    return True

largest = 0
for j in xrange(100, 1000):
    for k in xrange(j, 1000):
        if is_pallindrome(j*k):
            if (j*k) > largest: largest = j*k
print largest
kaffuffle
  • 11
  • 1
0

Each time it doesnot have to start from 999 as it is already found earlier.Below is a simple method using string function to find largest palindrome using three digit number

def palindrome(y):
    z=str(y)
    w=z[::-1]
    if (w==z):
        return 0
    elif (w!=z):
        return 1        
h=[]
a=999
for i in range (999,0,-1):
    for j in range (a,0,-1):
    l=palindrome(i*j)
    if (l==0):
        h=h+[i*j]               
    a-=1
print h
max=h[0]

for i in range(0,len(h)):
    if (h[i] > max):
    max= h[i]
print "largest palindrome using multiple of three digit number=%d"%max  
Anoop M
  • 49
  • 3
0

Here is my code to solve this problem.

lst = []
for i in range(100,1000): 
    for n in range(2,i) : 
        lst.append (i* n) 
        lst.append(i*i)

lst2=[]
for i in lst: 
    if str(i) == str(i)[::-1]:
        lst2.append(i)
print max(lst2) 
Darshi
  • 33
  • 1
  • 5
0

580085 = 995 X 583, where 906609 = 993 X 913. Found it only by applying brute-forcing from top to bottom!

0

Here is my Python code:

max_pal = 0
for i in range(100,999):
    for j in range(100,999):
      mult = i * j 
      if str(mult) == str(mult)[::-1]: #Check if the number is palindrome
          if mult > max_pal: 
              max_pal = mult
print (max_pal)
0
def div(n):
    for i in range(999,99,-1):
        if n%i == 0:
            x = n/i
            if x % 1 == 0:
                x = n//i
                if len(str(x)) == 3:
                    print(i)
                    return True
    return False


def palindrome():
    ans = []
    for x in range(100*100,999*999+1):
        s = str(x)
        s = int (s[::-1])
        if x - s == 0:
            ans.append(x)

    for x in range(len(ans)):
        y = ans.pop()
        if div(y):
            return y


print(palindrome())
0

Here is the function I made in python to check if the product of 3 digit number is a palindrome

Function:

def is_palindrome(x):
    i = 0
    result = True
    while i < int(len(str(x))/2):
        j = i+1
        if str(x)[i] == str(x)[-(j)]:
            result = True
        else:
            result = False
            break
        i = i + 1
    return result

Main:


max_pal = 0
for i in range (100,999):
    for j in range (100,999):
        x = i * j
        if (is_palindrome(x)):
            if x > max_pal:
                max_pal = x

print(max_pal)
0

Here is my solution for that:

lst1 = [x for x in range(1000)]
palindrome = []

def reverse(x):
    a = str(x)[::-1]
    return int(a)

x = 0
while x < len(lst1):
    for y in range(1000):
        z = lst1[x] * y
        if z == reverse(z):
            palindrome.append(z)
    x += 1

duppal = set(palindrome)
sortpal = sorted(duppal)
total = sortpal[-1]
print(sortpal)
print('Largest palindrome: ' + str(total))
-1

ReThink: efficiency and performance

def palindrome(n):    

    maxNumberWithNDigits = int('9' * n) #find the max number with n digits

    product = maxNumberWithNDigits * maxNumberWithNDigits 

    #Since we are looking the max, stop on the first match

    while True:        
        if str(product) == str(product)[::-1]: break;

        product-=1

    return product

start=time.time()
palindrome(3)
end=time.time()-start

palindrome...: 997799, 0.000138998031616 secs

Rudney
  • 1
  • 1
  • 2
    The palindrome 997799 is not a product of two 3 digit numbers, it has 11 and 90709 as prime factors. – rakvium Dec 01 '16 at 15:19