Skip to content

Instantly share code, notes, and snippets.

@coderodde
Last active September 20, 2025 07:02
Show Gist options
  • Select an option

  • Save coderodde/698fa48157b2aa5f1a9b553f694d5e9b to your computer and use it in GitHub Desktop.

Select an option

Save coderodde/698fa48157b2aa5f1a9b553f694d5e9b to your computer and use it in GitHub Desktop.
Generating string permutations in Javascript.
<!DOCTYPE html>
<html>
<head>
<title>Letter permutations</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<script>
const str = "ABCDEFGH";
function swap(arr, i, j) {
const temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
function loadPermutation(letters, indices) {
const permutation = [];
for (let i = 0; i < indices.length; ++i) {
permutation.push(letters[indices[i]]);
}
return permutation;
}
function generateNextPemutation(letters, indices) {
let i = indices.length - 2;
while (i >= 0 && indices[i] > indices[i + 1]) {
--i;
}
if (i === -1) {
return null;
}
let j = i + 1;
let min = indices[j];
let minIndex = j;
while (j < indices.length) {
if (indices[i] < indices[j] && indices[j] < min) {
min = indices[j];
minIndex = j;
}
++j;
}
swap(indices, i, minIndex);
++i;
j = indices.length - 1;
while (i < j) {
swap(indices, i++, j--);
}
return loadPermutation(letters, indices);
}
function getPermutations(letters) {
const indices = [];
// Set the initial indices:
for (let i = 0; i < letters.length; ++i) {
indices.push(i);
}
const permutations = [];
permutations.push(letters.split("")); // Initial permutation.
let letterPermutation;
while ((letterPermutation = generateNextPemutation(letters, indices)) !== null) {
permutations.push(letterPermutation);
}
const filter = new Set();
permutations.forEach((element, index, array) => {
filter.add(element.join(""));
});
const result = [];
for (const elem of filter) {
result.push(elem);
}
return [...filter];
}
let ta = Date.now();
const crOutput = getPermutations(str);
let tb = Date.now();
console.log("coderodde's version:", (tb - ta), "milliseconds.");
console.log("coderodde's output", crOutput);
function getRandom(min, max) {
const minCeiled = Math.ceil(min);
const maxFloored = Math.floor(max);
return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled);
}
function factorial(m) {
let num = 1;
for (let i = 1; i <= m; i++) {
num = num * i;
}
return num;
}
function check(A, B) {
for (let i = 0; i < A.length; i++) {
let a = 0;
for (let j = 0; j < A[i].length; j++) {
if (A[i][j] !== B[j]) {
a++;
}
// Use === instead of ==
if (a === B.length) {
return false; // <- forgot ;
}
}
}
return true;
}
function getCombinations(A) {
let x = A.length;
let B = [];
while (B.length < factorial(x)) {
let Y = [];
for (let i = 0; i < x; i++) {
// const instead of let:
const a = getRandom(0, (x));
if (!Y.includes(A[a])) { // <- !Y.include(A[a]) instead of .. == false!
Y.push(A[a]);
} else {
// i = i - 1;
--i; // <- simpler.
}
}
if (check(B, Y)) {
B.push(Y.join(""));
}
}
return B;
}
ta = Date.now();
const opResult = getCombinations(str);
tb = Date.now();
console.log("OP's version:", (tb - ta), "milliseconds.");
console.log("OP's output:", opResult);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment