『ビンゴ』解答


◆岩手県 高梨 さんからの解答。

配当に関する条件を読みかえて、

4回目に「ビンゴ」が成立しているときは,賭けたコインの200倍
5回目に「ビンゴ」が成立しているときは,賭けたコインの100倍
6回目に「ビンゴ」が成立しているときは,賭けたコインの50倍
7回目に「ビンゴ」が成立しているときは,賭けたコインの25倍
8回目に「ビンゴ」が成立しているときは,賭けたコインの15倍
9回目に「ビンゴ」が成立しているときは,賭けたコインの5倍
10回目に「ビンゴ」が成立しているときは,賭けたコインの5倍

のコインが手元に戻ってくる(毎回重複計算)、としても配当は同じになります。

また、各N回目で「ビンゴ」が成立している確率を独立事象だとしても配当の期待値は変わりません。

・4回目

数字4つの組み合わせ:244=10626
ビンゴになる組み合わせ:4
(中央を通る縦横斜めのみ)

・5回目

数字5つの組み合わせ:245=42504
ビンゴになる組み合わせ:8+4*20=88
(中央を通らないライン+通るライン)

・6回目

数字6つの組み合わせ:246=134596
ビンゴになる組み合わせ:8*20+4*202=920
(同上)

・7回目

数字7つの組み合わせ:247=346104
ビンゴになる組み合わせ:8*202+4*203=6080
(同上)

・8回目

数字8つの組み合わせ:248=735471
ビンゴになる組み合わせ:
8*203+4*204-42=28494
(同上-重複しているダブルビンゴ)
重複は中央を通る縦横斜めの二本の組み合わせ(42)のみ

・9回目

数字9つの組み合わせ:249=1307504
ビンゴになる組み合わせ:
8*204+4*205-488=100288
(同上)
重複は、
中央を通る縦横斜めの二本の組み合わせ(42*16)
中央通りとそれ以外の組で平行なもの(8)
中央通りとそれ以外の組で交わるもの(8*3*16)
の合計(488)

・10回目

数字10の組み合わせ:2410=1961256
ビンゴになる組み合わせ:
8*205+4*206-3728=275344
(同上)
重複は、
中央を通る縦横斜めの二本の組み合わせ(42*162
中央通りとそれ以外の組で平行なもの(8*16)
中央通りとそれ以外の組で交わるもの(8*3*162
の合計(3728)

以上よりコインを300枚賭けた時の配当の期待値は、

300* (200* 4
10626
+100* 88
42504
+50* 920
134596
+25* 6080
346104
+15* 28494
735471
+5* 100288
1307504
+5* 275344
1961256
)
=818.960911枚

【感想】

条件を読みかえて、案外すんなりいくかな?と思ったのですが……。
結局ほとんど力押しで解いてしまいました。
計算ミスが無いか非常に心配です(’’;。


◆北海道 小西 儀紀 さんからの解答。

【解答】

期待倍率 = 4424360
1716099
= 2.5781…倍

300枚賭けた場合の期待枚数 = 442436000
572033
= 773.44…枚

【詳細】

2列以上ビンゴしても無意味なので、1列ビンゴした段階で次の玉は取り出さずに終了することとする。
24個の玉からn個の玉を取り出すとき、
n-1個目まででビンゴせずにn個目の玉でビンゴする順列の総数をAn
n個目の玉でもビンゴしない順列の総数をBnとする。
また、n-1個目まででビンゴせずにn個目の玉を引いた時の順列の総数をCnとする。
つまり、Cn = An + Bnである。

玉を引いていないn = 0のとき、A0 = 0、B0 = 1、C0 = 1と定義する。

Cnはn-1個目でビンゴしていない順列に対してn個目を引いた順列の総数でもあり、
n個目の玉の選択肢は25-n通りなので、
Cn = Bn-1 * (25-n) と表せる。

従って、Anを求めればBnとCnも決定する。

中心(25)は初めから塗られているので、Anを、
ビンゴ列に中心が使われている順列の総数A1nと、
ビンゴ列に中心が使われていない順列の総数A2nに分けて考える。
(An = A1n + A2n)
y <0のときxCy = 0とすると、1 ≦ n ≦ 10の範囲で、
A1n = 2 * (n-1)! * 4 * (20Cn-4-6 * 16Cn-8-4 * 15Cn-9) + 2 * (n-1)! * 4 * (20Cn-4-9 * 16Cn-8)
= 2 * (n-1)! * 4 * (2 * 20Cn-4-15 * 16Cn-8-4 * 15Cn-9)
A2n = 8 * (n-1)! * (5 * 19Cn-5-5 * 3 * 16Cn-8-4 * 4 * 15Cn-9-1 * 5 * 15Cn-9-5 * 3 * 14Cn-10)-16 * (n-1)! * 15Cn-9
= 8 * (n-1)! * (5 * 19Cn-5-15 * 16Cn-8-23 * 15Cn-9-15 * 14Cn-10)

となる。

考え方は、
赤字部分は最終的にビンゴする列の数(中央を含む縦横2通り、斜め2通り、中央を含まない縦横8通り)、
青字部分はビンゴ列以外の組み合わせ(引き算部分はn個目を引く前に赤字のビンゴ列以外がビンゴしてしまう配置を除いている)、
緑字部分はn個のマス(ビンゴ列とそれ以外)を塗る順列のうち、最後にビンゴ列が塗られる順列の総数、
ピンク字部分は前半で縦と横が同時にビンゴする順列を重複して数えているので、その補正。

この式からA1n、A2n、An、Bn、Cn
n個目が引ける確率Dn = Dn-1 * Bn-1
Cn-1
(D0 = 1と定義する)、

n個目が引けてビンゴする確率En = Dn * An
Cn
期待倍率、300枚BET時の期待枚数を計算すると以下のようになる。

nA1nA2nAnBnCnDnEn倍率En * 倍率
00001110--
1000242410--
200055255210--
3000121441214410--
49609625492825502410.0003764354000.150574064
576809608640508992050985600.9996235650.0016939582000.338791643
63648009120045600096252480967084800.9979296070.0047054391000.470543949
713132800492480018057600171448704017325446400.9932241670.010351967500.517598344
839009600019474560058484160028561438080291462796800.98287220.019722056250.493051392
999232358406166379520160896153604408933939204569830092800.9631501450.033910922100.339109224
10219644006400162512179200382156185600623124472320066134009088000.9292392220.05369620350.268481014
 期待倍率2.578149629
期待枚数773.4448887

なお、期待倍率、期待枚数を分数で表すと
4424360
1716099
442436000
572033
となる。

(多倍長の扱える計算ソフトにて計算)

【備考】

ドラゴンクエストVIIIのカジノですね(^^

自分でも気になっていて、8個までは計算していました。
9個と10個を考慮した式に修正してみたのですが、青字部分の引き算で抜けがないか心配です…
簡単なプログラムで全順列を数えて、n = 9 までは正しいことを確認してあります。
(n = 10 は計算中)

さらに個数を増やした場合も、ビンゴ列以外でビンゴしないように青字の組み合わせを うまく引き算していけばよいのですが、面倒なので考えていません…(^^;


◆三重県 とくしん さんからの解答。

C言語でプログラムを書いて求めました。
プログラムは224個全ての穴の開け方に対してビンゴしているかどうかを調べるという極めて異常な方法で計算しています。
ビット演算を多用しているのでソースコードは読み辛いと思いますがその分高速に動作します。

出力結果

穴の数  ビンゴしている確率  丁度ビンゴする確率  配当金の期待値
   3    0.000000            0.000000              0.000000
   4    0.000376            0.000376             45.172219
   5    0.002070            0.001694            101.637493
   6    0.006776            0.004705            141.163185
   7    0.017128            0.010352            155.279503
   8    0.036850            0.019722            147.915417
   9    0.070761            0.033911            101.732767
  10    0.124457            0.053696             80.544304
  11    0.203392            0.078935              0.000000
  12    0.311040            0.107648              0.000000
  13    0.446032            0.134992              0.000000
  14    0.598912            0.152880              0.000000
  15    0.750609            0.151697              0.000000
  16    0.876234            0.125626              0.000000
  17    0.956522            0.080287              0.000000
  18    0.991322            0.034800              0.000000
  19    0.999435            0.008113              0.000000
  20    1.000000            0.000565              0.000000
  21    1.000000            0.000000              0.000000
期待倍率 = 2.578150
300枚賭けた時の配当金の期待値 = 773.444889

以下プログラム

#include <stdio.h>

#define BET 300 // 何枚賭けるか

/*
ボードの座標をビットで表す。
ボードとビットの対応は次のようにする

000001 000002 000004 000008 000010
000020 000040 000080 000100 000200
000400 000800        001000 002000
004000 008000 010000 020000 040000
080000 100000 200000 400000 800000
*/

// ビンゴするラインの定義。
const int c_nLine[12] =
{
	// 横
	0x00001F,
	0x0003E0,
	0x003C00,
	0x07C000,
	0xF80000,
	// 縦
	0x084421,
	0x108842,
	0x210084,
	0x421108,
	0x842210,
	// 斜め
	0x820041,
	0x088110,
};

// 配当金
const int c_nPay[25] =
{
			0,0,0,0,
	400,
	200,
	100,
	 50,
	 25,
	 10,
	  5,
			0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};

// 立っているビットの数を数える
inline int CountBits(int num)
{
	int i, s = 0;
	for(i = 1 ; i < 0x01000000 ; i <<= 1)	// 高速化の為下位24ビットのみ調べる
	{										// 本当はテーブル化を併用した方が速いのだが。
		s += i & num ? 1 : 0;
	}
	return s;
}

void main(void)
{
	int anCount[25];		// [n]箇所空いている場合の数
	int anTrueBingo[25];	// [n]箇所空いた盤面がビンゴしている確率(母数はanCount)
	int anJustBingo[25];	// [n]箇所目で丁度ビンゴする確率(母数はanCountのn倍)

	int i, j, n, b;
	double pay;

	for(i = 0 ; i < 25 ; i++)
	{
		anCount[i] = 0;
		anTrueBingo[i] = 0;
		anJustBingo[i] = 0;
	}
	for(i = 0 ; i < 0x01000000 ; i++)	// 1677万通りだからこそ出来る荒業
	{									// iはループカウンタ兼盤面のデータそのもの。
		n = CountBits(i);				// 空いている穴の数で分類
		anCount[n]++;
		b = -1;	// ビンゴ列の判定用に全ビットを立てる。下位24ビットでも可
		for(j = 0 ; j < 12 ; j++)
		{
			if(!((i ^ c_nLine[j]) & c_nLine[j])) // ある列でビンゴしているか判定
			{
				b &= c_nLine[j];// ビンゴしていた場合その列に含まれないビットを落とす
			}					// 全てのビンゴしている列の交点となるビットのみが残る
		}
		if(b != -1)	// 1列でもビンゴしていた場合
		{
			anTrueBingo[n]++;
			anJustBingo[n] += CountBits(b);	// ビンゴしている列の交点の数だけ加算
		}									// 交点=そこを抜くと全てのビンゴ列が消える点
	}
	pay = 0;
	printf("穴の数  ビンゴしている確率  丁度ビンゴする確率  配当金の期待値\n");
	for(i = 3 ; i < 22 ; i++)
	{
		pay += (double)anJustBingo[i] / anCount[i] / i * c_nPay[i];
		printf("  %2d    %8.6f            %8.6f            %10.6f\n", i,
				(double)anTrueBingo[i] / anCount[i],
				(double)anJustBingo[i] / anCount[i] / i,
				(double)anJustBingo[i] / anCount[i] / i * c_nPay[i] * BET
				);
	}
	printf("期待倍率 = %8f\n", pay);
	printf("%d枚賭けた時の配当金の期待値 = %8f\n", BET, pay * BET);
	rewind(stdin);getchar();
}


 『ビンゴ』へ

 数学の部屋へもどる