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

arsenal picture arsenal · Aug 25, 2011 · Viewed 28k times · Source
package testing.project;

public class PalindromeThreeDigits {

    public static void main(String[] args) {
        int value = 0;
        for(int i = 100;i <=999;i++)
        {
            for(int j = i;j <=999;j++)
            {
                int value1 = i * j;
                StringBuilder sb1 = new StringBuilder(""+value1);
                String sb2 = ""+value1;
                sb1.reverse();
                if(sb2.equals(sb1.toString()) && value<value1) {
                    value = value1;

                }

            }
        }

        System.out.println(value);
    }
}

This is the code that I wrote in Java... Is there any efficient way other than this.. And can we optimize this code more??

Answer

James Waldby - jwpat7 picture James Waldby - jwpat7 · Aug 26, 2011

We suppose the largest such palindrome will have six digits rather than five, because 143*777 = 111111 is a palindrome.

As noted elsewhere, a 6-digit base-10 palindrome abccba is a multiple of 11. This is true because a*100001 + b*010010 + c*001100 is equal to 11*a*9091 + 11*b*910 + 11*c*100. So, in our inner loop we can decrease n by steps of 11 if m is not a multiple of 11.

We are trying to find the largest palindrome under a million that is a product of two 3-digit numbers. To find a large result, we try large divisors first:

  • We step m downwards from 999, by 1's;
  • Run n down from 999 by 1's (if 11 divides m, or 9% of the time) or from 990 by 11's (if 11 doesn't divide m, or 91% of the time).

We keep track of the largest palindrome found so far in variable q. Suppose q = r·s with r <= s. We usually have m < r <= s. We require m·n > q or n >= q/m. As larger palindromes are found, the range of n gets more restricted, for two reasons: q gets larger, m gets smaller.

The inner loop of attached program executes only 506 times, vs the ~ 810000 times the naive program used.

#include <stdlib.h>
#include <stdio.h>
int main(void) {
  enum { A=100000, B=10000, C=1000, c=100, b=10, a=1, T=10 };
  int m, n, p, q=111111, r=143, s=777;
  int nDel, nLo, nHi, inner=0, n11=(999/11)*11;

  for (m=999; m>99; --m) {
    nHi = n11;  nDel = 11;
    if (m%11==0) {
      nHi = 999;  nDel = 1;
    }
    nLo = q/m-1;
    if (nLo < m) nLo = m-1;

    for (n=nHi; n>nLo; n -= nDel) {
      ++inner;
      // Check if p = product is a palindrome
      p = m * n;
      if (p%T==p/A && (p/B)%T==(p/b)%T && (p/C)%T==(p/c)%T) {
        q=p; r=m; s=n;
        printf ("%d at %d * %d\n", q, r, s);
        break;      // We're done with this value of m
      }
    }
  }
  printf ("Final result:  %d at %d * %d   inner=%d\n", q, r, s, inner);
  return 0;
}

Note, the program is in C but same techniques will work in Java.