about summary refs log blame commit diff stats
path: root/js/bird-words/beak.js
blob: a87bc0d6d666eef8a392dd54f0083c7094b11d67 (plain) (tree)












































                                                                                                                                   



                                                                       









                                                                                    


                                                                       

                                                                                         


                                                           


                         
         






                                                                                                                                    
 

                                                              
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('input.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 script = 'The @NOUN@ of @ADJECTIVE@ @NOUN@ was found in @PLACE@ where there was a partial inscription that read, @MARKOV 22@';

// example of how to use fillGaps to generate a story
console.log(wrap(prettyItUp(fillGaps(script, nouns, adjectives, places, markovChain, pairs)), 40));

// example of how to just use markov chain to generate a story
console.log(wrap(prettyItUp(story), 40));