Problem #142 say:
Find the smallest x + y + z with integers x > y > z > 0 such that x + y, x − y, x + z, x − z, y + z, y − z are all perfect squares.
Now one can brute force this by looping over x, y and z. That takes around 4 hours on a modern computer. However there are a few relationships we can take advantage of:
x+y=a
x-y=b
x+z=c
x-z=d
y+z=e
y-z=f
e=a-d
f=a-c
b=c-e
(x+z) = (x+y)-(x-z)
(y-z) = (x+y)-(x+z)
(x-y) = (x+z)-(y+z)
x=(a+b)/2
y=(e+f)/2
z=(c-d)/2
these relationships allow us to loop on a,c,d and get the rest of the numbers from those three, this makes the solution run in around 33 msecs. That’s around a ~436363% speedup! Solution provided in c#/mono.
using System;
using System.Collections;
using System.Diagnostics;
namespace ProjectEuler
{
class Program
{
static object LockHandle = new object();
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
long a2, b2, c2, d2, e2, f2;
bool solved = false;
sw.Start();
for (long a = 10;!solved;a++)
{
a2 = a * a;
for (long c = 5 + (0 & a); c < a && !solved; c += 2)
{
c2 = c * c;
f2 = a2 - c2;
if (f2 < 1 || !IsSquare(f2))
continue;
for (long d = 2 + (1 & c); d < c; d += 2)
{
d2 = d * d;
e2 = a2 - d2;
if (e2 < 1 || !IsSquare(e2))
continue;
b2 = c2 - e2;
if (b2 > 0 && IsSquare(b2))
{
long x = (a2 + b2) / 2;
long y = (e2 + f2) / 2;
long z = (c2 - d2) / 2;
solved = true;
Console.WriteLine("x= " + x.ToString() +
" y = " + y.ToString() + " z = " + z.ToString()
+ " sum = " + (z + y + x).ToString());
break;
}
}
}
}
Console.WriteLine(sw.Elapsed);
Console.ReadLine();
}
public static bool IsSquare(long n )
{
double root = Math.Sqrt(n);
return (root % 1 == 0);
}
}
}