Created
November 4, 2018 11:54
-
-
Save steve-taylor/c9ea9c5deb16b2e663991e06416efb9b to your computer and use it in GitHub Desktop.
Given a list of words, generate a list of random words that start with the same letter as the original words.
This file contains hidden or 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
#!/usr/bin/env node | |
const fs = require('fs'); | |
const util = require('util'); | |
const readline = require('readline'); | |
const crypto = require('crypto'); | |
const readFile = util.promisify(fs.readFile); | |
const rl = readline.createInterface({ | |
input: process.stdin, | |
output: process.stdout, | |
}); | |
async function question(prompt) { | |
return new Promise((resolve) => { | |
rl.question(prompt, resolve); | |
}); | |
} | |
async function main() { | |
const maxWordLength = parseInt(await question('Max word length [unlimited] '), 10) || 1000; | |
const numResults = parseInt(await question('Number of results [20]'), 10) || 20; | |
// Read dictionary and index by first letter | |
const data = await readFile('/usr/share/dict/words', 'utf8'); | |
const wordsByFirstLetter = data.split('\n').reduce((wordsByFirstLetter, word) => { | |
const normalizedWord = word.trim().toLowerCase(); | |
if (normalizedWord && normalizedWord.length <= maxWordLength) { | |
const firstLetter = normalizedWord[0]; | |
let words = wordsByFirstLetter[firstLetter]; | |
if (!words) { | |
words = []; | |
wordsByFirstLetter[firstLetter] = words; | |
} | |
words.push(normalizedWord); | |
} | |
return wordsByFirstLetter; | |
}, {}); | |
// For each input word, generate a random word starting with the same letter that doesn't match it. | |
const answer = await question('Enter some words to create a mnemonic > '); | |
const words = answer.trim().toLowerCase().split(' '); | |
for (let i = 0; i < numResults; ++i) { | |
const mnemonic = words.map((word) => { | |
const firstLetter = word[0]; | |
const candidateWords = wordsByFirstLetter[firstLetter]; | |
const maxRandomNumber = (2 ** 24) - 1; | |
let randomWord = word; | |
while (randomWord === word) { | |
const randomNumber = parseInt(crypto.randomBytes(3).toString('hex'), 16); | |
const randomIndex = Math.floor(randomNumber / maxRandomNumber * candidateWords.length); | |
randomWord = candidateWords[randomIndex]; | |
} | |
return randomWord; | |
}).join(' '); | |
console.log(mnemonic); | |
} | |
} | |
main().then(() => void process.exit(0)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment