Skip to content

Instantly share code, notes, and snippets.

@psenger
Last active October 23, 2021 06:40
Show Gist options
  • Select an option

  • Save psenger/7697790fd4b6f80c4b438db3df79fb62 to your computer and use it in GitHub Desktop.

Select an option

Save psenger/7697790fd4b6f80c4b438db3df79fb62 to your computer and use it in GitHub Desktop.
[Permutations and Combinations in JavaScript] #JavaScript #TestHelper
// https://code-boxx.com/javascript-permutations-combinations/#sec-combi
// Combinations refer to the number of variations we can create from a list of things. The order of things does not matter.
function allCombinations (items) {
// allCombinations () : return a list of all possible combinations
// PARAM items : array of items
let results = [];
for (let slots = items.length; slots > 0; slots--) {
for (let loop = 0; loop < items.length - slots + 1; loop++) {
let key = results.length;
results[key] = [];
for (let i = loop; i < loop + slots; i++) {
results[key].push(items[i]);
}
}
}
return results;
}
var fruits = ["Apple", "Banana", "Coconut"];
var combo = allCombinations(fruits);
console.table(combo);
function allPermutations (items) {
// allPermutations () : return a list of all possible permutations
// Credits: https://stackoverflow.com/questions/9960908/permutations-in-javascript
// PARAM items : array of items
let results = [];
function permute(arr, memo) {
var cur, memo = memo || [];
for (let i = 0; i < arr.length; i++) {
cur = arr.splice(i, 1);
if (arr.length === 0) {
results.push(memo.concat(cur));
}
permute(arr.slice(), memo.concat(cur));
arr.splice(i, 0, cur[0]);
}
return results;
}
permute(items);
return results;
}
var fruits = ["Apple", "Banana", "Coconut"];
var permutated = allPermutations(fruits);
console.table(permutated);
const permUcLcString = function*( input ) {
const letters = input.split("");
const permCount = 1 << input.length;
for (let perm = 0; perm < permCount; perm++) {
// Update the capitalization depending on the current permutation
letters.reduce((perm, letter, i) => {
letters[i] = (perm & 1) ? letter.toUpperCase() : letter.toLowerCase();
return perm >> 1;
}, perm);
const result = letters.join("");
yield result;
}
return;
}
for (const permUcLcStringKey of permUcLcString('SpFlWSCommander')) {
// eslint-disable-next-line
console.log(permUcLcStringKey);
}
/**
* Alice, Bob and Charlie is the same as Charlie, Bob and Alice.
*
* Permutations are for lists (order matters) and combinations are for groups (order doesn't matter).
*
* A joke: A "combination lock" should really be called a "permutation lock". The order you put the numbers in matters.
*
* The difference between combinations and permutations is ordering.
* With permutations we care about the order of the elements, whereas with combinations we don't.
* For example, say your locker “combo” is 5432. If you enter 4325 into your locker it won't open
* because it is a different ordering (aka permutation).
*
* @see https://lowrey.me/permutation-with-an-es6-javascript-generator-2/
* @param {*[]} elements - the values to perm
* @returns {Generator<*[]|*, void, *>}
* @example
* const y = Array.from( permutations(['A','B','C'] ) );
* console.log( JSON.stringify(y, null, 4));
* // [
* // ["A", "B", "C"],
* // ["B", "A", "C"],
* // ["B", "C", "A"],
* // ["A", "C", "B"],
* // ["C", "A", "B"],
* // ["C", "B", "A"]
* // ]
*/
const permutations = function*(elements) {
if (elements.length === 1) {
yield elements;
} else {
let [first, ...rest] = elements;
for (let perm of permutations(rest)) {
for (let i = 0; i < elements.length; i++) {
let start = perm.slice(0, i);
let rest = perm.slice(i);
yield [...start, first, ...rest];
}
}
}
};
modules.exports = permutations
/**
* Generate all permutations of a string (contains duplicates)
* @see https://www.w3resource.com/javascript-exercises/fundamental/javascript-fundamental-exercise-136.php
* @param str
* @returns {(*)[]|*[]|*}
*/
const stringPermutations = str => {
if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str];
return str
.split('')
.reduce(
(acc, letter, i) =>
acc.concat(stringPermutations(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)),
[]
);
};
console.log(stringPermutations('abc'));
console.log(stringPermutations('*$*'));
/**
["abc","acb","bac","bca","cab","cba"]
["*$*","**$","$**","$**","**$","*$*"]
*/
/**
* Unique Combinations
* @see https://lowrey.me/es6-javascript-combination-generator/
* @param {Object[]} elements - the elements to pair up in the combination
* @param {Number} length - the pairs of the combination
* @returns {Generator<*[], void, *>}
* @example
* const y = Array.from( combinations( ['a', 'b', 'c', 'A', 'B', 'C'], 2 ) )
* console.log( JSON.stringify(y, null, 4));
* // [
* // ["a", "b"], ["a", "c"], ["a", "A"], ["a", "B"], ["a", "C"],
* // ["b", "c"], ["b", "A"], ["b", "B"], ["b", "C"], ["c", "A"],
* // ["c", "B"], ["c", "C"], ["A", "B"], ["A", "C"], ["B", "C"]
* // ]
*/
const combinations = function*(elements, length) {
for (let i = 0; i < elements.length; i++) {
if (length === 1) {
yield [elements[i]];
} else {
let remaining = combinations(elements.slice(i + 1, elements.length), length - 1);
for (let next of remaining) {
yield [elements[i], ...next];
}
}
}
};
modules.exports = combinations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment