views:

75

answers:

4

I'm trying to solve Project Euler #9, which is http://projecteuler.net/index.php?section=problems&id=9.

I've looked through this code, and the logic seems right…but I'm not getting any output at all, not even the printfs in the loop. I'm (obviously) a C newbie, trying to learn from higher level languages…could you tell me what's going wrong?

#include <stdio.h>

int main(){
    unsigned int a=0, b=0, c=0;
    short int pass=0;
    while(!pass){
        //printf("a = %4d\n", a);
        a++;
        b=a;
        while(!pass){
            b++;
            c=1000-a-b;
            if(b>=c) break;
            if(a*a+b*b==c*c) pass = 1;
        }
    }
    printf("a=%d, b=%d, c=%d, a*b*c=%d, a+b+c=%d\n", a, b, c, a*b*c,a+b+c);
    return 1;
}

Thanks so much.

EDIT: Okay, I've fixed the floating point problem as shown above, but now a never goes above two for some reason, making it loop infinitely.

EDIT: I fixed some bugs, but still, it returns a=33, b=483, c=484, a*b*c=7714476, a+b+c=1000, which isn't quite right. :(

Wow, I was overcomplicating it. It works now. Thanks everyone.

+2  A: 
if(floor(sc) != sc) continue; // we only want integer values of c

It's possible that that floor(sc) is always inequel to sc. Because sc is a double, operations on it will introduce small errors. Try defining a small variable to signify "close enough" and check if it is within that range. See here for strategies around this.

Not sure if there are other issues with your code.

Ben Gartner
Okay, that makes sense. Is there a better way to check if a float/double doesn't have a decimal part that the float_equality(floor(double), double) technique?
aharon
@aharon: you need to use just integer arithmetic. Given a value for a and b, the value of c is controlled by the question (a + b + c = 1000). You simply need to check whether a*a + b*b = c*c. It takes a minute fraction of a second to come up with the answer on my fairly ordinary Mac - using the simplest double-nested for loops. It doesn't take a whole second to validate that there is just one answer, as the Project Euler question states.
Jonathan Leffler
+3  A: 

Don't compare floating point values using == or !=. Floating point numbers can play all sorts of tricks on you. Instead, try checking if sc is in some suitably small range near an integer, and you will have better luck.

Carl Norum
+2  A: 

Project Euler Problem #9 doesn't need square roots nor floats.

msw
Or integers bigger than 32 bits.
Jonathan Leffler
+1  A: 

When the values 'a = 1', 'b = 2' in the first pass of the inner loop fail (because the √5 is not an integer), the loop goes around again, with 'a = 1' and 'b = 3', and fails because √10 is not an integer, and, indeed, there is no value of N other than zero (which is excluded from your loop) for which √(N2 + 12) is itself an integer.

So, until you run out of the range at which separate integer values are separable, your code will continue running.

The code related to 'pass' and the conditions if(b>=c) break; and (even more so) if( (a-- + b-- + c) == 7) pass=1; are totally inscrutable. Rewrite the code there more clearly. I'm not even going to try and guess what that does; I suppose it is intended to limit the range such that 'a + b + c' is not greater than 7, or thereabouts, but I don't think it will achieve the desired effect - even if you ever got to execute it.

Referencing the Project Euler page, you are meant to find a Pythagorean triplet 'a, b, c' such that 'a < b < c' and 'a + b + c = 1000'. The factor 1000 does not appear in your program. Given a value of a and b, the relevant value of c is determined.

Jonathan Leffler
Yah, sorry about that—that was from a mistaken fix. the
aharon