日別アーカイブ: 2015-01-21

多人数あみだくじ

多人数あみだくじの仕組み

以前に3~16人のあみだくじを《あみだくじを引く》で発表しました。紙にくじを書いて線をなぞって引き当て先を決定する様子を描画する方式でした。今回は99人までの多人数であり、多対多の対応づけを決定し表示します。記述言語はJavaScriptで、参加人数ぶんのID番号に、乱数による固有値を対応づけ小さい順に並べ替えて人為的な操作と再現性を排除しています。

2次元配列とsort

トランプをシャッフルしたり、福引きの抽選玉をかき混ぜる処理をコンピュータで行うとき、乱数を使うことがあります。オリジナルデータに乱数で発生させた固有値を付加し多次元配列を形成します。

配列は2次元の場合が多いが並べ替える場合は工夫が必要です。2次元配列の並べ替えには《多次元配列を特定の深さにある要素でsortしたい》が参考になります。1次元配列でも可能であり以下に例を示します。

JavaScript変数は32ビットや64ビットであることが多く、1つの変数で2つの用途に使うことも可能です。ホテルの部屋番号を5012のように名づけ、先頭の5は階数を、次の012でその階の通算部屋番号を意味することに似ています。

多人数あみだくじから少し脱線しますが、このような部屋番号のコード化は1階から最上階まで一律に番号を割り振るよりも利便性が高いといえます。

上図のように生成した乱数値を上位16ビットに、ID番号を下位16ビットにすると並べ替えがperson.sort();のようにたった1行のコードで済みます。驚くべき簡便さです。

並べ替えはsort()関数に引数を省略しているので文字型として比較されます。ID番号を取り出すには65536の剰余を求めることによって得られます。

乱数を付加する場合、大小関係を持たせるためにID番号の先頭に付加することが肝要です。

サンプルコード

<html>
<body>
  <input type="number" id="stepper1" name="stepper1" min="3" max="99" value="20"/>
  <input type="button" onClick="saveValue('stepper1')" value="参加人数を設定し、このボタンをクリックする" />
</body>
<head>
<script type="text/javascript">
function saveValue(target){               // 多人数あみだくじ-OK3.html
  var NUMBER = document.getElementById(target).value;  // onClickの設定値を取り出す
  alert("《多人数あみだくじ》Version0.96\n参加人数="+NUMBER);
  var person = [];                        // +---------------+--------------+
  var member = [];                        // |生成した乱数値 | ID番号      |
  for(var i=0; i<NUMBER; i++){            // +---------------+--------------+
    w = Math.floor(Math.random()*65536);  // 0~65535までの乱数を発生させる
    person[i] = w * 65536 + i;            // 生成した乱数値とID番号を合成する
  }
  person.sort();                          // 小さい順に並び替える
  for(i=0; i<NUMBER; ++i){                // 移動先を把握する
    x = person[i] % 65536;
    member[x] = i;
  }
  for(i=0; i<NUMBER; ++i){                // 並び替えられた結果を表示する
    x = person[i] % 65536;
    v = "="+fmt(x);
    s = ":"+fmt(member[i]);
    document.write(fmt(i)+v+s+"<BR>");
  }
}
function fmt(n){                          // 右寄せで表示する
  return ("00"+n).slice(-2);
}
</script>
</head>
</html>

サンプルコードの解説

①11~12行で配列を定義する。
②13~16で乱数固有値とID番号を求める。
③17行で小さい順に並べ替える。
④18~21行で元のID番号の移動先を求め、逆リンクでたどれるように。
⑤22~27行であみだくじの結果を表示する。
⑥29~31行は右寄せで表示する関数。

雑感

くじの参加人数は3~99ですが、もっと多人数も可能ですのでサンプルコードを変更してください。ポイントは乱数の発生と並べ替えです。プログラミングの初心者には、今回のプログラムコードでホテルの部屋番号のように複数用途の使い方が参考になることでしょう。

使い方と表示結果の説明

直接、キー入力あるいは上下ボタンで参加人数を設定しスタートボタンをクリックします。表示結果で最初の番号は順番号で次は引き当てられた番号、最後の番号は元の番号の移動先です。

サンプル動作