# An algorithm that finds a sequence of numbers to fill a square grid

Given numbers 1,2,3,4,5,6,7,8 I need them to replace the x's so that each side adds up to the number in the centre.

*-*---*-*
|x| x |x|
*-*---*-*
|x| 12|x|
*-*---*-*
|x| x |x|
*-*---*-*


As a start I have looped over the numbers to find all of the possible combinations.

var range = [1,2,3,4,5,6,7,8];
var target = 12;
var matches = [];

for (x = 0; x < range.length; x ++){
for (y = 0; y < range.length; y ++){
if (y === x){
continue;
}
for (z = 0; z < range.length; z ++){
if (z === y || z === x){
continue;
}

if (range[x] + range[y] + range[z] === target){
matches.push([range[x], range[y], range[z]]);
}
}
}
}


Next I have joined the numbers together end to end

for (j=0; j < matches.length; j++){
for (k=0; k < matches.length; k++){
if (j==k) continue;
//if (matches[j][2] != matches[k][0]) continue;
for (l=0; l < matches.length; l++){
if (l==j || l==k) continue;
//if (matches[k][2] != matches[l][0]) continue;
for (m=0; m < matches.length; m++){
if (m==j || m==k || m==l) continue;
if (matches[l][2] != matches[m][0]) continue;
if (matches[m][2] != matches[j][0]){
console.log(matches[j], matches[k], matches[l], matches[m]);
}

}
}
}
}


I have not currently put a check in to make sure each combination of numbers is only used once, which is how I would solve this.

I really would like to know an overall better approach to solving this problem.

A solved cube would look like:

*-*---*-*
|1| 5 |6|
*-*---*-*
|8| 12|4|
*-*---*-*
|3| 7 |2|
*-*---*-*

• I really would like to know an overall better approach to solving this problem. but apperntly there is nothing to improve because you didn't solve it yet: which is how I would solve this Jun 22, 2017 at 16:01
• Are you interested in finding all solutions or is any solution sufficient? Is the side-length of the cube always 3? Are the numbers always 1-8? Is the sum always 12?
– le_m
Jun 22, 2017 at 23:00

While not a complete solution for your first example, you can do two things to help speed it up.

If you don't have to use an array of values, don't just use a min and max (though the code doesn't change much if you do use a range).

You also don't need the third for-loop. Your third number will always be target - x - y. If target isn't in the range, you can throw it away.

You can further limit your for loop because you don't need to go all the way through every number in both loops. Since you know that you can't have 2 numbers which are both greater than half of your target, you can go through just the first part in the first loop, and the second loop through the second part. This lets you trim off a good bit from your for loops.

I also ended up using it as a string for this part, since it makes the check for uniqueness a bit easier, though it's not strictly necessary. My reduce also ensures no double digits.

const min = 1;
const max = 8;
const target = 12;

const allCombinations = (target, min, max) => {
const combos = [];
for (let i = min; i <= target / 2 && i <= max; i++) {
for (let j = max; j >= target / 2 && i >= min && target - i - j >= min; j--) {
combos.push([i, j, target - i - j].sort().join(''));
}
}

return combos
.reduce((result, a) => result.concat(!result.includes(a) && a[0] !== a[1] && a[1] !== a[2] && a[2] !== a[0] ? a : []), []);
};

console.log(allCombinations(target, min, max));

• This looks really nice, however I am not sure how you would take this to a full solution? Jun 22, 2017 at 16:25