views:

101

answers:

4

This is what I have written so far. It compiles, and, as far as I can tell, it should 'work' - if you were to give your computer an infinite amount of time to compute the answer !

I was just wondering if anyone would please be able to give me a way to optimise this so that my program will tell me the highest palindromic number (the same both forwards and backwards eg, 91 * 99 = 9009;) formed by multiplying any two three-digit numbers.

 public class HighestPalindrome {
     public static void main(String[] args) {
    int number=0;
    int answer=0;

    search:
    for(int LoopOfFirstNumber=999;LoopOfFirstNumber<=100;LoopOfFirstNumber -= 3){
      for(int LoopOfSecondNumber=LoopOfFirstNumber;LoopOfSecondNumber<=100;LoopOfSecondNumber-=3)
      {
        number = LoopOfFirstNumber * LoopOfSecondNumber;
        if (number == reverse(number))
         {
          answer=number;
          System.out.println(answer);
          break search;
         }
      }
    }
  }

     //The code after this works fine, I believe. It will reverse any number given very quickly, I think the problem
     //is above....with the two for loops!

    private static int reverse(int n, int r) {
      if (n == 0) return r;
      System.out.println("This iteration returns " + n/10 + " and  " + 10*r+n%10);
      return reverse(n/10, 10*r+n%10);
    }

    public static int reverse(int n) {
     return reverse(n, 0);
    }
+1  A: 

Your for loop conditions is wrong:

LoopOfFirstNumber<=0

it should be:

LoopOfFirstNumber>=100

You should continue to loop till your loop counters are >= 100 which is the smallest 3 digit number.

Also once you find a palindrome, you need to break both the loops. Currently you are breaking only the inner loop. To fix this you need to use labeled break.

codaddict
Actually, it should be LoopOfFirstNumber > 100, since we want only three digit numbers...
Paul
Ah, thank you very much. I changed from having a '++' loop to a '--' because I thought this would be faster (was I right in this assumption actually?), but I forgot to edit the conditions ! Many thanks !
Actually...why would I want my for loop to stop after 100 iterations ? Wouldn't 999 have three digits also ?
You don't want to stop after 100, but your loop as originally posted counted down from 999. If you're counting up, you want to start at 100. Counting down should be faster, if you stop each loop when the current product is less than your current maximum palindrome - no point in testing whether any numbers less than that are palindromes.
Paul
Also, you're testing each number twice (because for any given values of first and second number, later on you'll test the same number with first and second swapped)
Paul
Thanks a lot, that's a great help ! Will have a quick go at doing those things and edit my post to see if I get what you're saying ! Thanks a lot ! :)
+1  A: 

The inner for loop doesn't need to start with 999, it can start with LoopOfSecondNumber = LoopOfFirstNumber:

Let's assume that there is a solution for which LoopOfSecondNumber = x > LoopOfFirstNumber = y. Then there would be a solution where the two numbers are switched: LoopOfFirstNumber = x, LoopOfSecondNumber = y => This solution would thus have been found earlier in the outer loop already.

This doesn't bring you much optimization though, in best case it takes you half of the time the original code took.

chiccodoro
+2  A: 

As you already guessed, the problem is in the nested loop. Try to figure out a few property of the numbers. Multiplication of two three digits number will always give a number having five or six digits. Since you are looking for the highest number, then it's expected to be six digit number starting with number 9 and since it's palindromic, it probably ends with number 9 as well. In short, you're expecting numbers in the form 9xyyx9.

Next, not all pairs of numbers can be multiplied and end with number 9. xx3 and xx3 will give xxxxx9, so does xx1 and xx9; but xx1 and xx8 will never multiply to xxxxx9.

Find properties like these, and try to filter which ones likely can be implemented easily into your search.

Lie Ryan
Ok, I see what you're trying to say (and thank you very much for taking the time to say it!).I'm just trying to think of a way to integate these things into my code. If I decremented my loop by 3 instead of 1 every iteration it would work, I believe ?
I just edited my code to include my revisions now, it still doesnt run :(
You are still doing `<=100`. Do `>=100` instead.
codaddict
@codaddict - I made that change and it worked straight away ! Thank you very much ! :) Can you explain why this is the case though please ? I was under the impression that the 2nd condition of the for loop specified a point at which to end the loop ? Surely with <=100, the for loop should keep cycling until my 999 is reduced to 100 (or break; is called), and >=100 should cause it to end straight away ? Obviously this is not the case, I am just a little confused ! :)Thank you very much again ! :)
@user476033: the second part of a for-loop specifies when the loop should keep going. IOW, the second part of the loop should evaluate to true if you want to continue looping, or evaluate to false when you want to stop looping.
Lie Ryan
@user476033: the code as you have right now may not give correct result, since it skips some valid possibilities. There are three pairs of potential last digits that can multiply to 5-6 digit number ending with 9: (1*9=9), (3*3=9), (7*7=49). That is, you need to search all of `xx1*xx9`, `xx3*xx3`, and `xx7*xx7`. That's testing at most 24300 combinations (or even less, if you apply a few more optimizations); compared to your original which tests at most 810000 combinations. In my computer, 24300 palindrome tests takes a blink of an eye to calculate.
Lie Ryan
@Lie Ryan: Ahh thank you, that really clears thinks up for me, especialy re the for loop ! In terms of implementing those 24,300 tests, what would you recommend ? I coud use 3 distinct for loops and overwrite an 'answer' variable with the highest value returned, but that seems somewhat messy. The only alternative I can think of would be one for loop, with 2 ifs inside it which would increment the value in the for loop once certain values are met - this seems quite messy also though. Have I missed something silly ? Thank you very much again btw, I have my program (to some degree!) now ! Thanks!
+1  A: 

Why don't you tackle it from the other side?

Create a set of all the palindrome numbers starting from 1000000 (1000*1000) and working down, should be fairly easy.

And then factorise them - though I guess you're going to need an algorithm for this :-(

Michael Wiles
for (int SetOfAllIntegers=999999;SetOfAllIntegers<=900000;SetOfAllIntegers-=3) { if (SetOfAllIntegers == reverse(SetOfAllIntegers)) { int answer=SetOfAllIntegers; System.out.println(answer); break; } }Is something like this what you mean ? :)
Apologies, I'm not sure how to post properly indented code in comments !