Search code examples
javaalgorithmmathpalindrome

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


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??


Solution

  • 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.