Random Name Generator
Given an array of example names, use a Markov-chain-like approach to generating new thematically similar names
by Tonio Loewald
CSS
p {
padding: 0;
margin: 0;
text-transform: capitalize;
}
JavaScript
const seed = [
'Aragorn',
'Elrond',
'Eowyn',
'Faramir',
'Theoden',
'Saruman',
'Gandalf',
'Legolas',
'Arwen',
'Gimli',
'Samwise',
'Frodo',
'Boromir',
'Denethor',
'Galadriel',
'Celeborn',
'Meriadoc',
'Peregrin',
'Sauron',
'Garstang',
'Radagast',
'Gollum',
'Shelob',
'Isildur',
'Elendil',
'Eldarion',
'Anarion',
'Grima',
'Glorfindel',
'Beregond',
'Fredegar',
'Smaug',
'Tinuviel',
'Luthien',
'Feanor',
'Beren',
'Turin',
'Maedhros',
'Hurin',
'Fingolfin',
'Finwe',
'Maglor'
]
function pick(array) {
return array[Math.floor(Math.random() * array.length)];
}
class NameGenerator {
// data is a map from character-pairs to observed successors,
// consider the examples "how", "now", "brown", "cow"
// the pair "ow" would have the following successors
// [undefined, undefined, "n", undefined] (undefined -> end of word)
constructor(examples) {
const data = {'': []};
examples.
map(s => s.toLowerCase()).
forEach(example => {
let pair = '';
data[pair].push(example[0]);
for(let i = 0; i < example.length; i++) {
pair = pair.substr(-1) + example[i];
if (! data[pair]) data[pair] = [];
if (data[pair].indexOf(example[i+1]) === -1) data[pair].push(example[i + 1]);
}
});
console.log(data);
this.data = data;
}
generate() {
let s = pick(this.data['']);
let next = pick(this.data[s]);
while(next){
s += next;
next = pick(this.data[s.substr(-2)]);
}
return s;
}
}
const generator = new NameGenerator(seed);
for(let i = 0; i < 1000; i++) {
p = document.createElement('p');
p.textContent = generator.generate();
document.body.appendChild(p);
}