2017年5月29日月曜日

開発環境

Think Perl 6: How to Think Like a Computer Scientist (Laurent Rosenfeld(著)、Allen B. Downey(著)、Oreilly & Associates Inc)の Part 1(Starting with the basics)、Chapter 11(Case Study: Data Structure Selection)の Markov Analysis、Exercise: 7.を JavaScript で取り組んでみる。

Exercise: 6.

cmudict-0.7b.txt

コード(Emacs)

HTML5

<pre id="output0"></pre>
<input id="file0" type="file">
<label for="len0"> length: </label>
<input id="len0" type="number" min="1" step="1" value="2">
<label for="count0"> count: </label>
<input id="count0" type="number" min="1" step="1" value="10">

<button id="run0">run</button>
<button id="clear0">clear</button>

<script src="sample7.js"></script>

JavaScript

let btn0 = document.querySelector('#run0'),
    btn1 = document.querySelector('#clear0'),
    pre0 = document.querySelector('#output0'),
    input_file0 = document.querySelector('#file0'),
    input_len = document.querySelector('#len0'),
    input_count = document.querySelector('#count0'),
    p = (x) => pre0.textContent += x + '\n',
    range = (start, end, step=1) => {
        let result = [];

        for (let i = start; i < end; i += 1) {
            result.push(i);
        }
        return result;
    };

let reader = new FileReader(),
    words = [],
    markov = {};

Array.prototype.pick = function (n) {
    let result = [],
        a = this.slice();

    range(0, n).forEach(
        () =>result.push(a.splice(Math.floor(Math.random() * a.length), 1))
    );
    return result;
};

let makeWords = () => {
    words = reader.result
        .split('\n')
        .map((line) => line.trim())
        .filter((line) => line !== '')
        .map((line) => line.split(/\s+/))
        .reduce((prev, next) => prev.concat(next), []);
    makeMarkov();
};
let makeMarkov = () => {
    let len = parseInt(input_len.value, 10);
    
    range(0, words.length - 2 * len)
        .forEach((i) => {
            let prefix = words.slice(i, i + len).join(' ') + ' ',
                suffix = words.slice(i + len, i + 2 * len).join(' ') + ' ';

            if (!markov[prefix]) {
                markov[prefix] = {};
            }
            markov[prefix][suffix] = 1;
        });
    makeText();
};
let makeText = () => {
    let count = parseInt(input_count.value, 10),
        prefix = Object.keys(markov).pick(1)[0],
        text = '';

    range(0, count)
        .forEach(() => {
            let suffix = Object.keys(markov[prefix]).pick(1)[0];
            
            text += (prefix + suffix);
            prefix = suffix;
        });
    p(text);
};


reader.onload = makeWords;

input_file0.onchange = () => reader.readAsText(input_file0.files[0]);
input_len.onchange = makeMarkov;
input_count.onchange = makeText;

let output = () => {
    if (words.length !== 0) {
        makeText();
    }
};

let clear = () => pre0.textContent = '';

btn0.onclick = output;
btn1.onclick = clear;

output();



















						

0 コメント:

コメントを投稿