Last active
January 5, 2022 11:39
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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