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 &lt; range.length; x ++){
    for (y = 0; y &lt; range.length; y ++){
        if (y === x){
            continue;
        }
        for (z = 0; z &lt; 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 &lt; matches.length; j++){
  for (k=0; k &lt; matches.length; k++){
    if (j==k) continue;
    //if (matches[j][2] != matches[k][0]) continue;
    for (l=0; l &lt; matches.length; l++){
      if (l==j || l==k) continue;
      //if (matches[k][2] != matches[l][0]) continue;
      for (m=0; m &lt; 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|
*-*---*-*
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) =&gt; {
  const combos = [];
  for (let i = min; i &lt;= target / 2 &amp;&amp; i &lt;= max; i++) {
    for (let j = max; j &gt;= target / 2 &amp;&amp; i &gt;= min &amp;&amp; target - i - j &gt;= min; j--) {
      combos.push([i, j, target - i - j].sort().join(''));
    }
  }
  
  return combos
    .reduce((result, a) =&gt; result.concat(!result.includes(a) &amp;&amp; a[0] !== a[1] &amp;&amp; a[1] !== a[2] &amp;&amp; a[2] !== a[0] ? a : []), []);
};

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