indexed-string-variation
Version:
Experimental JavaScript module to generate all possible variations of strings over an alphabet using an n-ary virtual tree
66 lines (65 loc) • 1.91 kB
JavaScript
export const defaultAlphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
function cleanAlphabet(alphabet) {
return Array.from(new Set(alphabet.split(''))).join('');
}
// calculates the level of a given index in the current virtual tree
const getLevel = (base, index) => {
let level = 0n;
let current = index;
let parent;
while (current > 0n) {
parent = (current - 1n) / base;
level++;
current = parent;
}
return level;
};
// Generates a string based on the given index and alphabet
function generateString(startIndex, alphabet) {
if (startIndex === 0n)
return '';
const n = BigInt(alphabet.length);
let result = '';
let l;
let f;
let rebasedPos;
let rebasedIndex;
let index = startIndex;
while (index > 0n) {
l = getLevel(n, index);
f = 0n;
for (let i = 0n; i < l; i++) {
f += n ** i;
}
rebasedPos = index - f;
rebasedIndex = ((rebasedPos % n) + n) % n; // ensure non-negative
result = alphabet[Number(rebasedIndex)] + result;
index = (index - 1n) / n;
}
return result;
}
export function* indexedStringVariation(options = {}) {
const alphabet = options.alphabet
? cleanAlphabet(options.alphabet)
: defaultAlphabet;
const from = options.from ?? 0n;
let iterations = 0;
let i = from;
while (true) {
const str = generateString(i, alphabet);
if (options.maxLen !== undefined && str.length > options.maxLen) {
break;
}
yield str;
i++;
iterations++;
if (options.to !== undefined && i > options.to) {
break;
}
if (options.maxIterations !== undefined &&
iterations >= options.maxIterations) {
break;
}
}
}
export default indexedStringVariation;