views:

167

answers:

5

Hi,

So on Project Euler the Problem 4 states the following:

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 tried the following:

    #include <stdio.h>
    #include <stdlib.h>

    int check(int result)
    {
        char b[7];
        sprintf(b, "%d", result);
        if (b[0] == b[5] && b[1] == b[4] && b[2] == b[3])
        {
            return 1;
        }
        else 
        {
            return 0;
        }
    }

    int main () {
        int i;
        int g;
        int final;
        for (i = 999; i > 99; i--)
        {
            for (g = 999; g > 99; g--)
            {
                if (check(g*i) == 1)
                {
                    final = g*i;
                    goto here;
                }
            }
        }
        here:
        printf("%d", final);
}

But, this does not work. Instead of the right answer, I get 580085, which I guess is a palindrome at least, but still not the right answer.

Let me explain my program starting from int main:

  1. int i and int g are my multipliers. They are those two three digit numbers.
  2. int final is the number that will store the largest palindrome.
  3. I start two for loops going to down to get every number possibility.
  4. I get out of the loop using a goto when the first palindrome is reached(probably should not but, it doesn't effect a small program like this too much).
  5. The first palindrome should be the biggest one possible since I am counting down from the top.

Let me now explain my check:

  1. First off since these are two three digit numbers multiplying together to determine the size a char would need to be to hold that value I went to a calculator and multiplied 999 * 999 and it ended up being 6 then I need to add one because I found out from one the questions I posted earlier that sprintf puts a \0 character at the end.
  2. Ok, now that I have a char and all, I copied result (which i*g in int main) and put it in char b[7].
  3. Then I just checked b to see if it equalled it self with by hard coding each slot I needed to check for.
  4. Then I returned accordingly, 1 for true, and 2 for false.

This seems perfectly logical to me but, it does not work for some weird reason. Any hints?

+10  A: 

This assumption is wrong:

The first palindrome should be the biggest one possible since I am counting down from the top.

You will check 999*100 = 99900 before 998*101 = 100798, so clearly you can´t count on that.

Emilio Silva
Beaten by 8 seconds...
Emilio Silva
Ohh... Thanks! Now I see what I am doing wrong.
thyrgle
+1  A: 

The first palindrome should be the biggest one possible since I am counting down from the top

The problem is that you might have found a palindrome for a large i and a small g. It's possible that there's a larger palindrome that's the product of j and k where:

i > j and
g < k

(I hope this makes sense).

Michael Burr
+1  A: 

The problem is that the first palindrome that you find is not the bigger one for sure.

Just an example:

i = 900, g = 850 -> 765000
i = 880, g = 960 -> 844800

The first one is smaller, but since you iterate first on i, then on g it will be discovered first.

Ok, they are not palindrome but the concept is the same..

Jack
A: 

A word on performance. You have the possibility of duplicating many of the products because you are using a pretty simple nested loop approach. For instance, you start with 999*999 and then 999*998, etc. When the inner loop finishes, you will decrement the outer loop and start again with 998*999, which is the same as 999*998.

Really, what you want to do is start the inner loop with the same value as the current outer loop value. This will eliminate your duplicate operations. Something like this...

for (i = 999; i > 99; i--)
{
  for (g = i; g > 99; g--)
  {
...

However, as Emilio pointed out, your assumption that the first palindrome you find will be the answer is incorrect. You need to compute the biggest numbers first, obviously. So you should try them in this order; 999*999, 999*998, 998*998, 999*997, 998*997, etc...

Haven't tested it but I think you want something like this (pseudo code):

x = 999;
n = 0;

while (++n <= x)
{
  j = x;
  k = j - n;

  while (j >= k)
  {
    y = j-- * k;
    if (check(y))
      stop looking
  }
}
JediPotPie
A: 

I think you are tackling this problem back to front. It would be more efficient to generate the palindromes from highest to lowest then check by factorizing them. First one that has two three digit factors is the answer.

e.g.

  bool found = false;
  for (int i = 998; i >= 100; i--)
  {
    char j[7];
    sprintf(j,"%d",i);
    j[3]= j[2];
    j[4]= j[1];
    j[5]= j[0];
    int x =atoi(j);
    int limit = sqrt((float) x);
    for (int z = 999; z >= limit; z--)
    {
      if (x%z==0){
        printf("%d",x);
        found = true;
        break;
      }
    }
    if (found) break;
  }
fivebob