Reputation: 8118
I've written a program that must find the solution to a EulerProblem. I want to train my program skills that's why I've signed up on euler.
This is the problem:
A Pythagorean triplet is a set of three natural numbers, a < b < c, for which, a^2 + b^2 = c^2
For example, 3^2 + 4^2 = 9 + 16 = 25 = 5^2.
There exists exactly one Pythagorean triplet for which a + b + c = 1000. Find the product abc.
and this is my code, but it runs soo slow, it take hours to give me the right abc.
static int findTriplet(int getal)
{
boolean test = false;
for(int a = 1; !test; a++)
for(int b = a+1; !test; b++)
for(int c = b+1; !test; c++)
{
if( a*a + b*b == c*c)
{
if(a+b+c == getal)
{
return (a*b*c);
}
}
}
return 0;
}
Is it possible to make the code much faster or is it normal that it takes hours?
Kind regards,
EDIT:
Thanks for helping. The !test boolean was useless sorry for that, This works :
static int findTriplet(int getal)
{
for(int a = 1; a < 1000; a++)
for(int b = a+1; b < 1000; b++)
for(int c = b+1; c < 1000; c++)
{
if( a*a + b*b == c*c)
{
if(a+b+c == getal)
{
return (a*b*c);
}
}
}
return 0;
}
I've also wrote a haskell variation that also does the trick.
Think this was easier in Haskell and more efficient.
Thaks for the tips.
Upvotes: 1
Views: 288
Reputation: 40679
Look at a tall, thin, right triangle, with base a
, height b
, and hypotenuse c
.
First a
and b
are always less that c
, and c = sqrt(a*a+b*b)
so as the other posters said, you only need to search over a
and b
.
You also know that a+b >= c
so there's no point in looking at small a,b
pairs.
Now, suppose you start with a=0, b=500
, so c==500
, and the total perimeter is 1000.
Now you increase a
by 1 and calculate the perimeter. It will be a little more than 1000.
Then you decrease b
by 1. Then the perimeter will be a little less than 1000.
Then increase a
by 1 until perimeter is > 1000 again.
So, as long as the perimeter is <= 1000, increase a
.
As long as it is > 1000, decrease b
.
If it is equal to 1000, you've got one answer. Then keep going.
You only need to do this as long as a<b
.
This algorithm should be O(N)
, because it doesn't waste time with small pairs.
Then all you have to do is prove to yourself that it won't miss any answers.
You do that by assuming there's a valid a,b
answer that it does miss, and show that's impossible.
Upvotes: 0
Reputation: 5637
In order to optimize this naive algorithm, you have first to understand that :
false
. You also take the risk to encounter an overflow of c
.Now, you know that you need to :
Here are some hints for easy optimisations :
And some hints for harder optimisations :
Upvotes: 5
Reputation: 178471
The last for
is redundant, you can find c = sqrt(a^2 + b^2)
, which will make your algorithm much faster.
Actually you will only have to check if there is a c
in N
[natural numbers] such that sqrt(a^2 + b^2) = c
, and check if a+b+c == 1000
This optmization will make your solution O(n^2)
instead O(n^3)
, 1000 times faster!
EDIT: As discussed in the comments:
c = sqrt(a^2 + b^2)
: c = 1000 - a -b
, but the important part is doing it in O(n^2)
and not O(n^3)
.Upvotes: 1