ジャンケンで決着がつくまでの回数(2)

ジャンケンを2〜10人で1万回を行う。
決着がつくまでにかかった回数の平均と標準偏差は次のようになった。

9人を超えるあたりから急激に増えるようだ。
以下、ソース。



for(var n = 2; n <= 10; n++) {
var b = [ ];
for(var k = 0; k < 10000; k++)
increment(b, getNumber(n));

print(b);
print(mean(b));
print(sigma(b));
}

function increment(b, n) {
if(b[n] == undefined)
b[n] = 1;
else
b[n]++;
}

function mean(b) {
var sum = 0;
var n = 0;
for(var i in b) {
var a = b[i];
sum += i * a;
n += a;
}
return sum / n;
}

function sigma(b) {
var sum = 0;
var m = mean(b);
var n = 0;
for(var i in b) {
var a = b[i];
var delta = i - m;
sum += delta * delta * a;
n += a;
}
return Math.sqrt(sum / n);
}

// 決着がつくまでにかかった回数を得る
function getNumber(n) {
var a = [ ];
for(var i = 0; i < n; i++)
a[i] = 0;

var counter = 1;
while(!janken(a))
++counter;

return counter;
}

// ジャンケンをする
function janken(a) {
var length = a.length;
for(var i = length - 1; i >= 0; i--) {
var r = Math.random() * 3;
a[i] = 1 << r;
}

var n = judge(a);
if(length != n)
a.length = n;
return n == 1;
}

// ジャンケンで何人残ったかを返す
function judge(a) {
var b = 0;
var length = a.length;
for(var i = length - 1; i >= 0; i--) {
b |= a[i];
if(b == 7) // あいこ
return length;
}

if(b == 1 || b == 2 || b == 4)
return length;

var c; // 勝った手
if(b == 3) // g, c
c = 1;
else if(b == 5) // g, p
c = 4;
else
c = 2;

var counter = 0;
for(var i = length - 1; i>= 0; i--) {
if(a[i] == c)
counter++;
}

return counter;
}

function print(str) {
WScript.Echo(str);
}