JavaScript で組み合わせを全て列挙する(表にする)プログラムを作ってみた

皆さん、こんにちは。管理人です。

今回は、\( {}_n \mathrm{C}_k \) に関連するプログラムを作成しました。より具体的には、\( n \) 個ある玉(ボール)の中から \( k \) 個のボールを選ぶパターン全てを表にするプログラムを JavaScript で作成しました。

プログラムを動かしてみよう

「玉の数」と「選択する玉の数」を入力して「送信」ボタンをクリックしてみてください。

ソースコード

<form id="form1" action="#">
    <label>玉の数: 
        <input type="number" step="1" min="1" max="10" value="5" id="ball-num">
    </label>
    <label id="box-num-label">選択する玉の数: 
        <input type="number" step="1" min="1" max="6" value="3" id="select-num">
    </label>
    <input type="button" onclick="count_up()" value="送信">
</form>
<div id="output"></div>
#ball-num, #select-num {
    width: 100px;
    margin-right: 15px;
}

#output {
    width: fit-content;
    margin-top: 10px;
    height: 250px;
    overflow: auto;
}

#output table {
    border-collapse: separate;
    border-spacing: 0;
    text-align: center;
}

#output table td, #output table th {
    padding: 2px 4px;
    border-right: solid 1px black;
    border-bottom: solid 1px black;
}

#output table th {
    border-top: solid 1px black;
    position: sticky;
    top: 0;
    background-color: violet;
}

#output table tr td:first-child {
    text-align: right;
    background-color: aquamarine;
}

#output table th:first-child,
#output table td:first-child {
	border-left: solid 1px black;
}
let boxNum; // 箱の数
let ballNum; // ボールの数
let isSelectedBall; // i + 1 番目のボールを選択する場合、isSelectedBall[i] は true となる
let output; // 一覧表となるもの
let id; // 番号
let selectNum; // 選択するボールの数

// lastPosition 以降のボールの中から remain 個のボールを選択すれば良い
function next(lastPosition, remain) {
    if (remain === 0) { // remain が 0 になった場合、すべてのボールが箱に入った(ラベリングが終わった)ことを意味する
        id++;
        // 残りの値を false にする
        for (let i = lastPosition; i < ballNum; i++) {
            isSelectedBall[i] = false;
        }

        // 表に書き出す
        output += ('<tr><td>' + id + '</td>');
        for (let i = 0; i < ballNum; i++) {
            if (isSelectedBall[i]) {
                output += ('<td>〇</td>'); // そのボールを選択する場合は '〇'
            } else {
                output += ('<td>-</td>'); // そのボールを選択しない場合は '-'
            }
        }
        output += '</tr>';
    } else {
        for (let i = lastPosition; i <= ballNum - remain; i++) {
            // i 番目のボールを選択する
            for (let j = lastPosition; j < i; j++) {
                isSelectedBall[j] = false;
            }
            isSelectedBall[i] = true;
            remain--;
            next(i + 1, remain);
            remain++;
        }
    }
}

const count_up = () => {
    // 初期化
    id = 0;
    isSelectedBall = new Array(ballNum);

    // フォームからボールの数と箱の数を受け取る
    ballNum = Number(document.getElementById("ball-num").value);
    selectNum = Number(document.getElementById("select-num").value);

    // 表のヘッダー部分
    output = '<table><thead><tr><th>id</th>';
    for (let i = 1; i <= ballNum; i++) {
        output += ('<th>' + i + '番目の玉</th>');
    }
    output += '</tr></thead><tbody>';

    next(0, selectNum); // 数え上げ

    output += '</tbody></table>';
    document.getElementById("output").innerHTML = output; // 表を出力する
}
let boxNum;
let ballNum;
let isSelectedBall;
let output;
let id;
let selectNum;

function next(lastPosition, remain) {
    if (remain === 0) {
        id++;
        for (let i = lastPosition; i < ballNum; i++) {
            isSelectedBall[i] = false;
        }
        output += ('<tr><td>' + id + '</td>');
        for (let i = 0; i < ballNum; i++) {
            if (isSelectedBall[i]) {
                output += ('<td>〇</td>');
            } else {
                output += ('<td>-</td>');
            }
        }
        output += '</tr>';
    } else {
        for (let i = lastPosition; i <= ballNum - remain; i++) {
            for (let j = lastPosition; j < i; j++) {
                isSelectedBall[j] = false;
            }
            isSelectedBall[i] = true;
            remain--;
            next(i + 1, remain);
            remain++;
        }
    }
}

const count_up = () => {
    id = 0;
    isSelectedBall = new Array(ballNum);

    ballNum = Number(document.getElementById("ball-num").value);
    selectNum = Number(document.getElementById("select-num").value);

    output = '<table><thead><tr><th>id</th>';
    for (let i = 1; i <= ballNum; i++) {
        output += ('<th>' + i + '番目の玉</th>');
    }
    output += '</tr></thead><tbody>';

    next(0, selectNum);
    output += '</tbody></table>';
    document.getElementById("output").innerHTML = output;
}

注意

このプログラムを WordPress に実装する際は、意図しないコメントアウトを防ぐために、コメントなしの JavaScript を実装したほうが良いかも知れません。

コメント

タイトルとURLをコピーしました