2016年9月29日木曜日

開発環境

アルゴリズムパズル(Anany Levitin (著)、Maria Levitin (著)、黒川 洋 (翻訳)、松崎 公紀 (翻訳)、オライリージャパン)の中級パズル、58.(ソートして、もう1回ソート(Sorting Once, Sorting Twice)))をJavaScriptで。

コード(Emacs)

HTML5

<div id="output0"></div>
<button id="shuffle0">シャッフル!</button>
<button id="row_sort0">各行をソート</button>
<button id="col_sort0">各列をソート</button>

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

JavaScript

{
    'use strict';
    Array.prototype.shuffle = function () {
        var shuffled = [],
            len = this.length,
            len0,
            i;

        for (len0 = len; len0 > 0; len0 -= 1) {
            i = Math.floor(Math.random() * len0);
            shuffled.push(this[i]);
            this.splice(i, 1);
        }
        for (i = 0; i < len; i += 1) {
            this[i] = shuffled[i];
        }
    };
    Array.range = (start, end, step) => {
        var nums = [],
            i;

        if (step === 0) {
            throw {
                name: 'ValueError',
                message: 'range() arg 3 must not be zero',
            };
        }
        if (step === undefined) {
            step = 1;
        }
        if (end === undefined) {
            end = start;
            start = 0;
        }
        if (step > 0) {
            for (i = start; i < end; i += step) {
                nums.push(i);
            }
        } else {
            for (i = start; i > end; i += step) {
                nums.push(i);
            }
        }
        return nums;
    };

    let div_output = document.querySelector('#output0'),
        button_shuffle = document.querySelector('#shuffle0'),
        button_row_sort = document.querySelector('#row_sort0'),
        button_col_sort = document.querySelector('#col_sort0');

    let card = (suit, n) => {
        return {
            suit: suit,
            n: n,
            toString: () => {            
                if (n < 10) {
                    n = ' ' + n;
                }
                return `${suit}${n}`;
            },
        };
    };
    let suits = ['♣️','♦️', '❤️', '♠️'];
    let cards = suits.map(
        (suit) => Array.range(1, 14).map(
            (n) => {
                return card(suit, n);
            }
        ))
        .reduce((x, y) => x = x.concat(y), []);

    let table;
    let output = () => {
        return '<table><tr><td>' +
            table.map((row) => {
                return row.join('</td><td>');
            })
            .join('</td></tr><tr><td>') +
            '</td></tr></table>';
    };
    let shuffle = () => {
        cards.shuffle();

        table = [cards.slice(0, 13),
                 cards.slice(13, 26),
                 cards.slice(26, 39),
                 cards.slice(39)];

        div_output.innerHTML = output();
    };
    let orderFunc = (card1, card2) => {
        if (card1.n === card2.n) {
            return suits.indexOf(card1.suit) -
                suits.indexOf(card2.suit);
        }
        return card1.n - card2.n;
    };
    let rowSort = () => {
        table.forEach((row) => {
            row.sort(orderFunc);
        });
        div_output.innerHTML += '<br>' + output();
    };
    let colSort = () => {
        Array.range(table[0].length).forEach((i) => {
            let array = table.map((row) => row[i]);
            array.sort(orderFunc);        
            table.forEach((row) => {
                row[i] = array.shift();
            });
        });
        div_output.innerHTML += '<br>' + output();
    };
    button_shuffle.onclick = shuffle;
    button_row_sort.onclick = rowSort;
    button_col_sort.onclick = colSort;
}

0 コメント:

コメントを投稿