ポーションの蓋を集めるには何本必要?

 というわけで,前回の「ポーションの蓋を全種類集めるには何本買えばいいかの期待値を求めよ」の答えです.

 今のところ出ている答えはJさんの13~14本.

まず確認すること

 まず基本的な事として,「1回につき確率nで手に入る物を手に入れるまでの期待値は1/n回」です.

 そうですよね?6本あってある1本(たとえばパッケージに書いてある奴)がほしい場合,買わなければいけない期待値は6本ですよね?

 証明は・・・面倒なので良いですか?(ぇ

それでは本番

 まず,6本あるうちの,6本どれでも良いので欲しいです.手に入る確率は6/6.手に入れるまでの期待値は6/6本.

 次に,6本あるうちの,手に入れた1本を除く5本のうちのどれかが欲しいです.手に入る確率は5/6.期待値は6/5本.

(中略)

 次に,6本あるうちの,手に入れた4本を除く2本のうちのどれかが欲しいです.手に入る確率は2/6.期待値は6/2本.

 次に,6本あるうちの,手に入れた5本を除く1本が欲しいです.手に入る確率は1/6.期待値は6/1本.

 よって,次のような式になります.本数をD(=Drink)とすると

D = 6/6 + 6/ 5 + 6/4 ・・・ 6/1

= 6 * ( 1/6 + 1/5 + 1/ 4 ・・・ 1/1)

= 14.7本

 あとJさん,惜しかったですw

 なお,箱買いもチマチマ貧乏くさく買うのも数学的に同じです.

※3/22追記

 レイスタさんの情報より,箱買いするともれなく蓋が6種類2セット,カードがかぶらないように12種類付くらしいです.それだと・・・答えは箱のうちの右半分か左半分6本を買い占めれば蓋に関しては全コンプできるみたいですw

計算ツールを作りました.

 計算ツールです.一発で計算できます.使用は自己責任で.

 なお,正確に分数の形で計算しているので,37個以上で計算させるのは・・・マシンパワーに余程の自信があるならどうぞ.

 なんでそんなにかかるのかって?足し算ごとに毎回約分してる†1ので,最大公約数を見つけるのに時間がかかってるんです.37回目では,887820718293231097と8992153642237365600の最大公約数を求めるのに凄まじい時間がかかります。。。

 かといって約分をしないためにBigIntegerを使っても・・・多分37回目ぐらいには凄いケタになってて,結局時間がかかりそうなので・・・.

 まあ,小数を使って近似を取るのが一番なんですが,それでは負けな気がしまして(何

 さっきのも一発で計算できます.

20060321-01.PNG

 カードの方も計算させて見ました.

20060321-02.PNG

 これはひどい.

//あれ・・・?ソフト内の文章がいろいろと変ですね.必要なのは個数ですよね.

//・・・記念に放置!(何

カードと蓋をどっちも集めるには?

 とりあえずカード集めておけば余程運が悪くない限り集まってますけどねw

 まず,6本27枚あるうちの,6本27本どれでも良いので欲しいです.手に入る確率は 6*27/6*27 .手に入れるまでの期待値は 6*27/6*27 本.

 次に,6本27枚あるうちの,5本26本どれかが欲しいです.どちらかが手に入る確率は 1-(5*26/5*27) .手に入れるまでの期待値は (6*27)/(6*27-5*26) 本.

 ここまでは分かったんですが・・・この先はもしや蓋が手に入った場合とビンが手に入った場合で場合分けしなくてはいけないのでは・・・?

 場合分けだとすると,調べるのは・・・2^27 = 134217728通りも調べなきゃ・・・.

 ここでスタックオーバーフローした†2ので強制終了させておきます_| ̄|○

 ただ,105.069本と大差ないとは思います.

 だれかうまい方法を教えてください・・・.

ためしに1億人に買わせてみた

ランダムで買わせて見てどうなるかチェック!(w

人数を多くすればするほど値が正確になっていきますね.

/*ShokuganがShakugan(灼眼)に見えたのはここだけの秘密だ*/


>java Shokugan 1
合計:12個
人数:1人
平均:12.0個

>java Shokugan 10 合計:136個 人数:10人 平均:13.6個
>java Shokugan 100 合計:1323個 人数:100人 平均:13.23個
>java Shokugan 1000 合計:14518個 人数:1000人 平均:14.518個
>java Shokugan 10000†3 合計:146880個 人数:10000人 平均:14.688個
>java Shokugan 100000†4 合計:1465555個 人数:100000人 平均:14.65555個
>java Shokugan 1000000†5 合計:14715499個 人数:1000000人 平均:14.715499個
>java Shokugan 10000000†6 合計:147033596個 人数:10000000人 平均:14.7033596個
>java Shokugan 100000000†7 合計:1469669029個 人数:100000000人 平均:14.69669029個

誤差,0.00330971.こんな話もあったし,これぐらいが限界かなぁ.

//まあ,リンク先の話は・・・ずいぶん前のだとは思うけど.

ちなみにソースは


/*
 * 作成日: 2006/03/21
 *
 */
public class Shokugan {
	public static final int[] STATE = {1,2,4,8,16,32};
	static java.util.Random rnd=new java.util.Random();
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		long count = 0;
		long people = Integer.parseInt(args[0]);
		for(int i=0;i < people;i++){
			count += buy();
		}
		double average = (double)count / people;
		System.out.println("合計:"+count+"個");
		System.out.println("人数:"+people+"人");
		System.out.println("平均:"+average+"個");
	}
	public static long buy(){
		long turn = 0;
		long state = 0;
		while(state != 63){
			state |= STATE[rnd.nextInt(STATE.length)];
			turn ++;
		}
		return turn;
	}
}

です.(一部隠れてるので,コピーして貼り付けてください.)

//Eclipse便利だよなぁ・・・.

  • †1: そうじゃないとすぐにLongのケタが溢れる
  • †2: 実際,27回もジャンプしてスタック領域足りるのか?
  • †3: 1万人
  • †4: 10万人
  • †5: 100万人
  • †6: 1000万人
  • †7: 1億人