I quickly wrote this code to test when all sides and diagonals of a cuboid a,b,c,d,e and f are all integers. It seems to work just fine but it takes way too much time for higher and higher values to loop through (for ex 10000+).
Is there any way to make this code run faster ? or maybe someway to get rid of that nasty three nested for loops ?
I thought of a few ways to reduce the complexity of this code but it doesn’t go through all combinations which is something I want to happen.
const generate_good_cuboid = () => {
let good_couples = [];
let couples = [];
for (let a = 1; a < 10000; a++) {
for (let b = 1; b < 10000; b++) {
for (let c = 1; c < 10000; c++) {
let e_squared = Math.pow(a, 2) + Math.pow(c, 2);
let e = Math.sqrt(e_squared);
if (Number.isInteger(e)) {
let d_squared = Math.pow(a, 2) + Math.pow(b, 2);
let d = Math.sqrt(d_squared);
if (Number.isInteger(d)) {
let f_squared = Math.pow(b, 2) + Math.pow(c, 2);
let f = Math.sqrt(f_squared);
if (Number.isInteger(f)) {
good_couples.push({ a, b, c, d, e, f });
}
}
}
}
}
}
return couples;
};
console.log(generate_good_cuboid());
3
Answers
You can avoid the inner loop if the a & b sides doesn’t give an integer. Also you could use
(d|0) === d
which is faster.A trivial optimisation would be to compute
d
(froma
andb
) and check for its integer-ness before looping over allc
.Further, you could avoid generating duplicates such as
a=3, b=4
anda=4, b=3
by limiting your results toa < b < c
, and permute your solutions if you need all of them. Then you can optimisefor (let b = a; b < 10000; b++)
andfor (let c = b; c < 10000; c++)
(although this doesn’t really change complexity).Last but not least, you could generate all known-good sets of Pythagorean triples up-front (only once), and then just search through those to find two triples (triangles) that share one side, and check whether the other two legs (catheti) form a Pythogorean triple as well. Use any of the known algorithms (generating Pythagorean triples, tree of primitive Pythagorean triples, Efficiently find all the Pythagorean triplets, best way to generate Pythagorean triples etc.) for the first part.
Here is a solution that uses the Tree of primitive Pythagorian triples to generate all Pythagorian triples whose greatest element is less than your limit.
Then it creates a graph (adjacency list) where one integer has a link with another if they are the lesser two members of a Pythagorian triple.
Finally it checks if these can be combined to the desired combinations of a, b, and c:
The script finds 8 solutions (ignoring permutations) when the limit is 1000; it repeats the job for 10000 (128 solutions) and 100000 (1457 solutions).