// array[i] gives the number of players on team i function permuteTeams(array, callback) { let n = 0; result = [] for (let i = 0; i < array.length; i++) { n += array[i]; result = result.concat(new Array(array[i]).fill(i)); } teamsUsed = clone(array); while (true) { callback(clone(array)); let x = n-2; teamsUsed[result[x+1]] -= 1; teamsUsed[result[x]] -= 1; while (true) { if (result[x] < result[x+1]) { firstX = teamsUsed[result[x]] == 0; var swap = 9999; var validSwap = false; for (let y = x+1; y < n; y++) { if (result[y] < swap && result[y] > result[x] && (!firstX || array[result[y]] != array[result[x]])) { if (teamsUsed[result[y]] == 0) { let ok = true; for (let t = 0; t < result[y]; t++) { if (teamsUsed[t] == 0 && categories[result[y]] == categories[t]) { ok = false; } } if (ok) { swap = result[y]; validSwap = true; } } } } if (validSwap) { teamsUsed[swap]++; result[x] = swap; z = 0; for (y = x+1; y < n; y++) { while (teamsUsed[z] == categories[z]) z++; result[y] = z; teamsUsed[z]++; } break; } } x--; if (x < 0) break; teamsUsed[result[x]]--; } if (x < 0) break; } }