コンプガチャと銀のエンゼル

複数種類のカードを集める(コンプガチャ)のと、同じカードを複数集める(銀のエンゼル)のはどっちが大変なの? ということを確めてみる。
どちらも公平に、1種類あたり100枚に1枚の確率で引けるとしよう。必要な枚数(種類)を変えて、それぞれ何枚引けば揃えられるか、10000回試行した平均を示す。

必要数 同種 コンプ
1 100 100
2 200 150
3 300 183
4 400 208
5 500 229

こうして見ると、コンプの方が簡単じゃないか、と感じる。


しかし、実際に引いてみると、この計算通りの感触にはならない。その理由は2つある。


1つは、コンプの場合、当たる確率の見積りを間違えやすいことだ。当たり外れで考えると、最初は持っていないカードが多く、どれか1種引けば当たりになる。後半はダブりが多くなるので、段々当たりの割合が減っていく。当たりカードを持っているときの、残りの当たりを引く確率を表にすると以下のようになる。

持っている種類 当たり確率
0 20枚に1枚
1 25枚に1枚
2 33枚に1枚
3 50枚に1枚
4 100枚に1枚

最初に当たりが出やすいので、甘く見ていると、思ったより当たりにくいと感じるのだろう。


もう1つの理由は、引いた結果からの見積りのしやすさの違いである。1番目の表のように見積りができたとしても、それが正しくない場合がある。1種類の場合は、当たりが出る確率は引けば引くほど正確に分かるようになる。一方、コンプの場合は、当たるまで1枚も引けないため、引ける確率を見積ることができない。他の当たったカードから類推するしかないのだが、最後の1種類は他の1/10の確率でしか出現しない、となると予想と大きくずれてしまうだろう。このように、運営がずるをしても気づきにくいことが問題となる。


また、引いたカードの内容、あるいは個人情報を運営が把握している場合には、どちらにしても引くカードの操作ができてしまう。こうした状況でくじ引きをするのであれば、運試めしだとは思わずに、雰囲気を楽しむものだと割り切った方が良いだろう。

;利用した関数
(defun silver (q n)
  (do ((c 0 (1+ c))
       (m 0))
      ((= m n) c)
    (if (zerop (random q))
        (incf m))))

(defun complete (q n)
  (do ((c 0 (1+ c))
       (m (make-vector n)))
      ((notany 'null m) c)
    (let ((a (random q)))
      (if (< a n) (setf (elt m a) t)))))