Skip to content

Instantly share code, notes, and snippets.

@DanElliottPalmer
Last active January 5, 2022 11:39
Show Gist options
  • Save DanElliottPalmer/5def9ffe0d134bfc32d1c89b1cf56adc to your computer and use it in GitHub Desktop.
Save DanElliottPalmer/5def9ffe0d134bfc32d1c89b1cf56adc to your computer and use it in GitHub Desktop.
Generates a list of unique id that can only exist if the word version of the number successfully contains all the digits in the word.
const NUMBERS_TO_LETTERS = new Map([
["0", "o"],
["1", "i"],
["2", "z"],
["3", "e"],
["4", "h"],
["5", "s"],
["6", "b"],
["7", "l"],
["8", "b"],
["9", "g"],
]);
function replaceLetters(value, str) {
const numbers = String(value).split("");
const numbersLetters = numbers.map((num) => NUMBERS_TO_LETTERS.get(num));
let numberIndex = 0;
let replacedWord = str.toLowerCase();
for (let i = 0; i < replacedWord.length; i++) {
if (replacedWord[i] === numbersLetters[numberIndex]) {
replacedWord =
replacedWord.substring(0, i) +
numbers[numberIndex] +
replacedWord.substring(i + 1);
numberIndex++;
if (numberIndex >= numbers.length) return replacedWord;
}
}
return undefined;
}
const UNITS = [
"zero",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
];
const TEENS = [
"ten",
"eleven",
"twelve",
"thirteen",
"fourteen",
"fifteen",
"sixteen",
"seventeen",
"eighteen",
"nineteen",
];
const TENS = [
"",
"ten",
"twenty",
"thirty",
"fourty",
"fifty",
"sixty",
"seventy",
"eighty",
"ninety",
];
const MEGAS = [
"",
"thousand",
"million",
"billion",
"trillion",
"quadrillion",
"quintillion",
"sextillion",
"septillion",
"octillion",
"nonillion",
"decillion",
"undecillion",
"duodecillion",
"tredecillion",
"quattuordecillion",
];
const TRUNC = Math.trunc;
const INTL_FORMATTER = new Intl.ListFormat("en-GB", {
style: "long",
type: "conjunction",
});
function getTriplets(value) {
const triplets = [];
while (value > 0) {
triplets.push(value % 1000);
value = TRUNC(value / 1000);
}
return triplets;
}
function getUnitGroups(value) {
return [TRUNC((value / 100) % 10), TRUNC((value / 10) % 10), value % 10];
}
function numberToWords(value) {
const words = [];
const triplets = getTriplets(value);
// Zero
if (triplets.length === 0) return UNITS[0];
let triplet;
let tripletWords;
let word;
let hundreds, tens, units;
for (let i = triplets.length - 1; i >= 0; i--) {
triplet = triplets[i];
tripletWords = [];
if (triplet === 0) continue;
[hundreds, tens, units] = getUnitGroups(triplet);
if (hundreds > 0) {
tripletWords.push(`${UNITS[hundreds]} hundred`);
}
if (!(tens === 0 && units === 0)) {
switch (tens) {
case 0:
tripletWords.push(UNITS[units]);
break;
case 1:
tripletWords.push(TEENS[units]);
break;
default:
if (units > 0) {
tripletWords.push(`${TENS[tens]} ${UNITS[units]}`);
} else {
tripletWords.push(TENS[tens]);
}
break;
}
}
word = INTL_FORMATTER.format(tripletWords);
if (MEGAS[i] !== "") {
word = `${word} ${MEGAS[i]}`;
}
words.push(word);
}
return INTL_FORMATTER.format(words);
}
function* getUniqueId(start = 0) {
while (true) {
const words = numberToWords(start);
const replacedWords = replaceLetters(start, words);
yield [start, replacedWords];
start++;
}
}
const ids = getUniqueId(0);
for (let i = 0; i < 10000000; i++) {
let id = ids.next().value;
if (id[1]) console.log(`ID: ${id[0]} - ${id[1].trim()}`);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment