Skip to content

Instantly share code, notes, and snippets.

@d3x0r
Last active November 29, 2018 00:12
Show Gist options
  • Save d3x0r/fdc19f5f0c5a99de4df5129ff5b2aa13 to your computer and use it in GitHub Desktop.
Save d3x0r/fdc19f5f0c5a99de4df5129ff5b2aa13 to your computer and use it in GitHub Desktop.
Generalized loops to iterate all combinations and permutations
//
// call initRowPerms( [], /* number of columns to permutate */, /* number from */, /*number to */ )
//
//----------------------------------------------------------------------------
// generate combinations to a callback
//----------------------------------------------------------------------------
function getCombinations(cb, cols, from, to) {
var indexes = [];
for (var n = 0; n < cols; n++) indexes.push(from);
var curIndex = cols - 1;
var comb = new Array(cols);
do {
for (var n = 0; n < cols; n++) comb[n] = indexes[n];
if (!cb(comb)) return;
do {
indexes[curIndex]++;
if (indexes[curIndex] > to) {
indexes[curIndex] = from;
curIndex--;
if (curIndex < 0) return;
continue;
}
curIndex = indexes.length - 1;
break;
} while (1);
} while (1);
}
// demonstrate usage of getCombinations
// call generator with a callback that saves output for test code below.
function runCombinationGenerator(output, cols, from, to) {
function saveOutput(val) {
output.push(val);
return true; // allow continue. ( similar to [].find() )
}
getCombinations(saveOutput, cols, from, to);
}
//----------------------------------------------------------------------------
// generator method.
//----------------------------------------------------------------------------
function* genCombinations(cols, from, to) {
var indexes = [];
for (var n = 0; n < cols; n++) indexes.push(from);
var curIndex = cols - 1;
var comb = new Array(cols);
do {
for (var n = 0; n < cols; n++) comb[n] = indexes[n];
yield comb;
do {
indexes[curIndex]++;
if (indexes[curIndex] > to) {
indexes[curIndex] = from;
curIndex--;
if (curIndex < 0) return;
continue;
}
curIndex = indexes.length - 1;
break;
} while (1);
} while (1);
}
// demonstrate usage of genCombinations (generator)
// call generator with a callback that saves output for test code below.
function runCombinations(output, cols, from, to) {
var iter = genCombinations(cols, from, to);
var next;
while ((next = iter.next()).value) {
output.push(next.value);
}
}
//----------------------------------------------
// BEGIN Test code.....
//----------------------------------------------
var comb = [];
runCombinations(comb, 4, 1, 9);
console.log("combination length 4 of 1-9 elements %d total", comb.length);
console.log(JSON.stringify(comb));
//----------------------------------------------
// END Test code.....
//----------------------------------------------
//----------------------------------------------------------------------------
// generator method.
//----------------------------------------------------------------------------
// utility function to test if duplicate is in array.
function findPair(array, a, b, cols) {
//console.log( "find:", a, b, cols );
if (a == b) return findPair(array, a, b + 1, cols);
if (b >= cols) {
if (a < cols - 1) return findPair(array, a + 1, 0, cols);
return false;
}
if (array[a] == array[b]) return true;
if (b + 1 != a) return findPair(array, a, b + 1, cols);
else return findPair(array, a, b + 2, cols);
}
function* genPermutations(cols, range) {
var indexes = [];
for (var n = 0; n < cols; n++) indexes.push(0);
var curIndex = cols - 1;
var perm = new Array(cols);
do {
if (!findPair(indexes, 0, 1, cols, range)) {
for (var p = 0; p < cols; p++) perm[p] = indexes[p];
yield perm;
}
do {
indexes[curIndex]++;
if (indexes[curIndex] == range) {
indexes[curIndex] = 0;
curIndex--;
if (curIndex < 0) return;
continue;
}
curIndex = indexes.length - 1;
break;
} while (1);
} while (1);
}
// demonstrate usage of getCombinations (generator)
// call generator with a callback that saves output for test code below.
function runPermutationGenerator(output, cols, range) {
var iter = genPermutations(cols, range);
var next;
while ((next = iter.next()).value) {
output.push(next.value);
}
}
//----------------------------------------------------------------------------
// generate combinations to a callback
//----------------------------------------------------------------------------
function getPermutations(cb, cols, range) {
var indexes = [];
for (var n = 0; n < cols; n++) indexes.push(0);
var curIndex = cols - 1;
var perm = new Array(cols);
do {
if (!findPair(indexes, 0, 1, cols, range)) {
for (var p = 0; p < cols; p++) perm[p] = indexes[p];
cb(perm);
}
do {
indexes[curIndex]++;
if (indexes[curIndex] == range) {
indexes[curIndex] = 0;
curIndex--;
if (curIndex < 0) return;
continue;
}
curIndex = indexes.length - 1;
break;
} while (1);
} while (1);
}
// demonstrate usage of getPerms
// call generator with a callback that saves output for test code below.
function runPermutations(output, cols, range) {
function saveOutput(val) {
output.push(val);
return true; // allow continue. ( similar to [].find() )
}
getPermutations(saveOutput, cols, range);
}
//----------------------------------------------------------------------------
// generator method.
//----------------------------------------------------------------------------
// call initPerms( [], 5 ) ; // permuatations of 0-4
function initPerms(output, cols, range) {
var indexes = [];
for (var n = 0; n < cols; n++) indexes.push(0);
var curIndex = cols - 1;
do {
if (!findPair(indexes, 0, 1, cols, range)) {
var perm = indexes.map(v => v);
output.push(perm);
}
do {
indexes[curIndex]++;
if (indexes[curIndex] == range) {
indexes[curIndex] = 0;
curIndex--;
if (curIndex < 0) return;
continue;
}
curIndex = indexes.length - 1;
break;
} while (1);
} while (1);
}
//-----------------------
// BEGIN TEST CODE
//-----------------------
var perms = [];
initPerms(perms, 4, 9);
console.log("permutation length 4 of 9 elements %d total", perms.length);
perms = [];
runPermutationGenerator(perms, 4, 9);
console.log("permutation length 4 of 9 elements %d total", perms.length);
perms = [];
runPermutations(perms, 4, 9);
console.log("permutation length 4 of 9 elements %d total", perms.length);
console.log(JSON.stringify(perms));
//-----------------------
// END TEST CODE
//-----------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment