const fs = require('fs'); const wrap = (str, width) => { const words = str.split(' '); return words.reduce((output, word) => { if (output.length === 0 || output[output.length - 1].length + word.length + 1 > width) { output.push(word); } else { output[output.length - 1] += ' ' + word; } return output; }, []).join('\n'); }; const prettyItUp = string => { return string.charAt(0).toUpperCase() + string.slice(1) + "!"; } let corpus = fs.readFileSync('corpus.txt', 'utf8'); let words = corpus.toLowerCase().replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g,"").replace(/\n/g, " ").replace(/\s{2,}/g, " ").split(" "); let markovChain = new Map(); for (let i = 0; i < words.length - 2; i++) { let pair = words[i] + ' ' + words[i + 1]; if (!markovChain.has(pair)) { markovChain.set(pair, []); } markovChain.get(pair).push(words[i + 2]); } let pairs = Array.from(markovChain.keys()); let randomPair = pairs[Math.floor(Math.random() * pairs.length)]; let story = randomPair; const storyLength = 100; for (let i = 0; i < storyLength; i++) { let nextWords = markovChain.get(randomPair); if (!nextWords) { break; } randomPair = randomPair.split(' ')[1] + ' ' + nextWords[Math.floor(Math.random() * nextWords.length)]; story += " " + randomPair.split(' ')[1]; } let nouns = fs.readFileSync('nouns.txt', 'utf8').split('\n'); let adjectives = fs.readFileSync('adjectives.txt', 'utf8').split('\n'); let places = fs.readFileSync('places.txt', 'utf8').split('\n'); const fillGaps = (script, nouns, adjectives, places, markovChain, pairs) => { return script.split('@').map(part => { if (part.startsWith('NOUN')) { return nouns[Math.floor(Math.random() * nouns.length)] + ' '; } else if (part.startsWith('ADJECTIVE')) { return adjectives[Math.floor(Math.random() * adjectives.length)] + ' '; } else if (part.startsWith('PLACE')) { return places[Math.floor(Math.random() * places.length)]; } else if (part.startsWith('MARKOV')) { const length = parseInt(part.split(' ')[1]); let chain = ''; let pair = pairs[Math.floor(Math.random() * pairs.length)]; for (let j = 0; j < length; j++) { const nextWords = markovChain.get(pair); const nextWord = nextWords[Math.floor(Math.random() * nextWords.length)]; chain += ' ' + nextWord; pair = pair.split(' ')[1] + ' ' + nextWord; } return chain; } else { return part; } }).join(''); }; const scriptFile = process.argv[2]; if (!scriptFile) { console.log(wrap(prettyItUp(story), 40)); } else { const script = fs.readFileSync(scriptFile, 'utf8'); console.log(wrap(prettyItUp(fillGaps(script, nouns, adjectives, places, markovChain, pairs)), 40)); }