2016年10月6日木曜日

開発環境

アルゴリズムパズル(Anany Levitin (著)、Maria Levitin (著)、黒川 洋 (翻訳)、松崎 公紀 (翻訳)、オライリージャパン)の中級パズル、65.(ビット列の推測 (Code Guessing))をJavaScriptで。

65.(ビット列の推測 (Code Guessing))

コード(Emacs)

HTML5

<label for="n0">ビット列の桁数 n = </label>
<input id="n0" type="number" min="1" step="1" value="10">
<button id="start0">推測開始</button>
<div id="output0"></div>
<button id="show0">提示</button>

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

JavaScript

{
    'use strict';
    let answer,
        input_n = document.querySelector('#n0'),
        div_output = document.querySelector('#output0'),
        button_start = document.querySelector('#start0'),
        button_show = document.querySelector('#show0');

    let ones = (bits) => {
        return bits.reduce((x, y) => x + y, 0);
    };
    let randomBits = (n) => {
        let bits = [];
        
        for (let i = 0; i < n; i += 1) {
            bits[i] = Math.random() < 0.5 ? 0 : 1;
        }
        return bits;
    };
    let reply = (bits, answer) => {
        let count = 0;
        for (let i = 0; i < bits.length; i += 1) {
            count += bits[i] === answer[i] ? 1 : 0;
        }
        div_output.innerHTML += `${bits.join('')}: ${count}箇所一致<br>`;
        return count;
    };
    let bitsShow = (m, n) => {
        let bits = [];

        for (let i = 0; i < m; i += 1) {
            bits[i] = 0;
        }
        for (let i = m; i < n; i += 1) {
            bits[i] = 1;
        }
        return bits;
    };
    let start = () => {
        div_output.innerHTML = '';
        
        let n = parseInt(input_n.value, 10);
        let answer = randomBits(n);
        let guess = [];
        let m = 0;
        let count;
        let prev;
        button_show.onclick = () => {
            if (m === 0) {
                let bits = bitsShow(0, n);
                count = reply(bits, answer);
                prev = count;
                m += 1;
            } else {
                let bits = bitsShow(m, n);
                let count0 = reply(bits, answer);
                guess[m - 1] = prev < count0 ? 0 : 1;
                prev = count0;
                m += 1;
                if (m === n) {
                    count0 = ones(guess);
                    guess.push(count > count0 ? 1 : 0);
                    div_output.innerHTML +=
                        `${guess.join('')} (推測値)<br>` +
                        `${answer.join('')} (正解)`;
                }
            }
        };    
    };

    button_start.onclick = start;
    button_show.onclick = start;

    start();
}

0 コメント:

コメントを投稿