技術

すべらない話: 正二十面体のサイコロを振って全員に当たる割合

気になったので調べてみた。
本来なら数式を考えればすぐに確率が分かるはずだけど、プログラムを組んで試行してみた。

モデルはこの前の「すべらない話 Merry Christmas!聖夜スペシャル」。
話者17人、二十面体には話者の名前と残った3面には☆マーク(☆マークが出たらまだ喋ってない人を選択する)、サイコロを振った回数19回という条件。

ちなみに実際の話者と、話のタイトルは以下のとおり。(敬称付けたいけど冗長になるので断腸の思いで敬称略)

・話者
松本人志, 千原ジュニア, 宮川大輔, ほっしゃん。, 河本準一, ケンドーコバヤシ, 兵動大樹, 小籔千豊, 木村祐一, 設楽統, 塚地武雅, 若林正恭, 桂雀々, ガダルカナル・タカ, コラアゲンはいごうまん, コカドケンタロウ, バカリズム

・タイトル(順番通り)
宮川 角刈り
松本 立体駐車場にて…
松本 親子連れ
木村 松本さんの結婚パーティー
河本 国歌斉唱
コラアゲン ヌーディスト
雀々 11才の時 母が蒸発
設楽 相方 日村の歯
兵動 ゴミ捨てにて
ジュニア 兄 せいじからの電話
小藪 なんとも言えない顔
バカリズム タクシードライバー
ほっしゃん 整体師の鼓動
コカド ユキちゃん
塚地 きたろう
コラアゲン 矢沢永吉
ケンコバ ジェット風呂
若林 バーモント秀樹
ガダルカナルタカ スズメバチ

・ソース

# -*- coding: utf-8 -*-

u'''
すべらない話のサイコロシミュレータ
'''

import random

speakers = [
	u'松本人志', u'千原ジュニア', u'宮川大輔', u'ほっしゃん。',
	u'河本準一', u'ケンドーコバヤシ', u'兵動大樹', u'小籔千豊',
	u'木村祐一', u'設楽統', u'塚地武雅', u'若林正恭', u'桂雀々',
	u'ガダルカナル・タカ', u'コラアゲンはいごうまん', u'コカドケンタロウ', u'バカリズム',
]

special = u'☆'
pips = speakers + ([special] * 3)

choice_count = 19
trial_count = 1000000

def main():
	u'''
	trial_count回試行して、全員喋った割合を表示する
	'''
	everyone_talked_count = 0
	for i in xrange(trial_count):
		if everyone_talked(trial()):
			everyone_talked_count += 1
	
	print u'%d回の試行中、全員喋った割合: %.4f%%' % (
		trial_count,
		float(everyone_talked_count) / trial_count * 100,
	)


def trial():
	u'''
	1番組について試行する
	choice_count回サイコロを振って、話者とその選択された回数の表(辞書)を返す
	'''
	selected_count_table = dict([(speaker, 0) for speaker in speakers])
	for i in xrange(choice_count):
		selected_count_table[choice_pip(selected_count_table)] += 1
	return selected_count_table


def choice_pip(selected_count_table):
	u'''
	サイコロの目をランダムで選ぶ
	specialが出たらselected_count_tableの値が0のキーの中からランダムで返す
	'''
	choiced = random.choice(pips)
	if choiced == special:
		# 全員喋ってる場合は、話者から一人選ぶ
		# まだ全員喋ってない場合は、未選択の話者から一人選ぶ
		if everyone_talked(selected_count_table):
			choiced = random.choice(speakers)
		else:
			not_selected = [k for k, v in selected_count_table.iteritems() if v == 0]
			choiced = random.choice(not_selected)
	return choiced


def everyone_talked(selected_count_table):
	u'''
	全員喋ったかどうかを調べる
	selected_count_tableの値に0が無ければTrue, それ以外はFalseを返す
	'''
	for k, v in selected_count_table.iteritems():
		if v == 0:
			return False
	return True


if __name__ == "__main__":
	main()

・結果
百万回で試行するとだいたい0.1%前後になるみたい。
無粋なことは言いますまい。

・一番笑った話
リアルタイムで見てたときはどれもまんべんなくという感じだったが、タイトル一覧をつくるために録画を30秒飛ばしで見てたら、コカドさんの「ユキちゃん」が一番思い出し笑いしてしまった。

コメントを残す

メールアドレスが公開されることはありません。



※画像をクリックして別の画像を表示

This site uses Akismet to reduce spam. Learn how your comment data is processed.