I stumbled upon this unsolved problem of math named Euler's brick. I wrote a program in C++
to generate solutions for Euler's brick problem.
It searches from 1 to 10,000
in about 10 seconds
.
It took 10.977153 minutes
to search from 1 to 50,000
.
How can I increase the performance further so I can search for larger limits? Are there any important optimizations that I am missing?
Here is my current code:
#include <iostream>
#include <vector>
#include <array>
#include <math.h>
#include <chrono>
inline bool is_whole(double x) {
return x - int(x) == 0;
}
int main() {
auto start = std::chrono::high_resolution_clock::now();
std::vector<std::array<int, 3>> solutions = {};
unsigned long int i = 1;
unsigned long int limit = 10000;
while (i < limit) {
int a = i;
for (int b = i; b < limit; b++) {
if (is_whole(sqrt(double((a*a + b*b))))) {
for (int c = b; c < limit; c++) {
if (
is_whole(sqrt(double((a*a + c*c)))) &&
is_whole(sqrt(double((b*b + c*c))))
) {
std::array<int, 3> sol = {a, b, c};
solutions.push_back(sol);
}
}
}
}
++i;
}
auto stop = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
std::cout << solutions.size() << " solutions found in " << duration.count() << " microseconds..." << std::endl;
for (std::array<int, 3> sol : solutions) {
if (is_whole(sqrt(sol[0] * sol[0] + sol[1] * sol[1] + sol[2]))) {
std::cout << "\n\nPerfect cuboid found!!" << "[" << sol[0] << ", " << sol[1] << ", " << sol[2] << "]\n" << std::endl;
}
std::cout << "[" << sol[0] << ", " << sol[1] << ", " << sol[2] << "], ";
}
return 0;
}
The smallest Euler brick has sides (a,b,c)=(240,117,44) and face polyhedron diagonals d_(ab)=267, d_(ac)=244, and d_(bc)=125.
What am I missing? \$\endgroup\$O(N^3)
. Could you reduce this toO(N^2) + O(N)
. 1: Find all integer pairs that have a perfect diagonal. 2: Match pairs with other pairs with a common side. This is the CS solution. Best would be to come up with a Maths solution that has a non brute force technique. \$\endgroup\$