Pretty much none of these answers are right.
Your question is:
Where is the bug in my code?
If you are using double-precision arithmetic to solve a problem in the integers, you are doing something wrong. Do not use Math.Pow
at all, and particularly do not use it to extract cube roots and expect that you will get an exact integer answer.
So how should you actually solve this problem?
Let's be smarter about not doing unnecessary work. Your program discovers that 13 + 123 = 93 + 103, but also that 123 + 13 = 103 + 93, and so on. If you know the first one then you can know the second one pretty easily.
So what should we do to make this more efficient?
First, b
must be larger than a
. That way we never waste any time figuring out that 13 + 123 = 123 + 13.
Similarly, d
must be larger than c
.
Now, we can also say that c
and d
must be between a
and b
. Do you see why?
Once we put these restrictions in place:
for (int a = 1; a <= 1000; ++a)
for (int b = a + 1; b <= 1000; ++b)
for (int c = a + 1; c < b; ++c)
for (int d = c + 1; d < b; ++d)
if (a * a * a + b * b * b == c * c * c + d * d * d)
Console.WriteLine($"{a} {b} {c} {d}");
Your program becomes a lot faster.
Now, there are ways to make it faster still, if you're willing to trade more memory for less time. Can you think of some ways that this program is wasting time? How many times are the same computations done over and over again? How can we improve this situation?
We might notice for example that a * a * a
is computed every time through the three inner loops!
for (int a = 1; a <= 1000; ++a)
{
int a3 = a * a * a;
for (int b = a + 1; b <= 1000; ++b)
{
int b3 = b * b * b;
int sum = a3 + b3;
for (int c = a + 1; c < b; ++c)
{
int c3 = c * c * c;
int d3 = sum - c3;
for (int d = c + 1; d < b; ++d)
if (d3 == d * d * d)
Console.WriteLine($"{a} {b} {c} {d}");
}
}
}
But we could be even smarter than that. For example: what if we created a Dictionary<int, int>
that maps cubes to their cube roots? There are only 1000 of them! Then we could say:
for (int a = 1; a <= 1000; ++a)
{
int a3 = a * a * a;
for (int b = a + 1; b <= 1000; ++b)
{
int b3 = b * b * b;
int sum = a3 + b3;
for (int c = a + 1; c < b; ++c)
{
int c3 = c * c * c;
int d3 = sum - c3;
if (dict.HasKey(d3))
{
d = dict[d3];
Console.WriteLine($"{a} {b} {c} {d}");
}
}
}
}
Now you don't have to compute cubes or cube roots of d; you just look up whether it is a cube, and if it is, what its cube root is.