Home > Archives > 2026年09月24日

2026年09月24日

確率が気になったので

国道トレカで「全部揃った」と「1枚足りてない」がどのくらいの確率なんだろうと気になったので計算したりしてみた.

まず,全部揃う確率.これはクーポンコレクター問題(食玩問題)なので,k 種類のクーポンが n 回までで揃う確率は,第2種スターリング数 S(n, k)(n 回を k 分割するやり方の数)を用いて k! * S(n, k) / k^n になる.Wikipedia の記述を見ると S(n, k) = k*S(n-1, k) + S(n-1, k-1) の再帰で計算できるらしいので,S(n, n) = 1 と S(n, 0) = S(0, k) = 0 をベースにしてメモ化しつつ Python で実装:

from functools import cache
@cache
def st2(n,k):
  if n == k: return 1
  if n == 0 or k == 0: return 0
  return k*st2(n-1,k) + st2(n-1,k-1)

そしてこれを使って確率が計算できる:

from math import factorial
def p(n,k): 
  return factorial(k) * st2(n,k) / (k**n)

1パックに C は 4枚入ってて,22パック開けたので n = 88枚.C の総数は R1 が k = 45枚と R2 が k = 46枚.これで一通り揃う確率はそれぞれ p(88,45) = 0.000258 とか p(88,46) = 0.000132 とか程度.88枚でのコンプリートはどちらも難しそうな確率.

次に,「1枚足りない」の確率を考えてみると,n回を k-1 分割して,そこに k 種類のうちの k-1 種類をマッピングするので,ほぼ同じ形の (k! / 1!) * S(n, k-1) / k^n のはず.これは k = 45 で 0.003033,k = 46 で 0.001714 とか程度.

うーん,だいぶ思ってたより低すぎる気がする.実際には 1パックの4枚には重複がなさそうな気もするので,それを入れないとダメか?

パック中の4枚に重複がないのは真面目に考えるのメンドイからシミュレーションしてしまう:

from random import sample
def sim(k,n,d,NN):
  xs=list(range(k))
  hh = [0 for _ in range(k+1)]
  for _ in range(NN):
    hs=[0 for _ in range(k)]
    for i in range(n // d):
      cs=sample(xs,k=d)
      for c in cs:
        hs[c] += 1
    c=sum( 1 for h in hs if h == 0)
    hh[c] += 1
  return hh

45種類で 1枚ずつ 88回引くのを 1M回やってみたら(sim(45,88,1,1000000)),全部揃ったのが 243回, 1枚足りないのが 2991回.これは数式で見積もった値とほぼほぼ一致.

45種類で 4枚ずつ 22回引いてみたら(sim(45,88,4,1000000)),全部揃ったのが 483回, 1枚足りないのが 5135回.1枚ずつに比べて2倍くらいの確率だけど,全部揃うのは 0.05% だし,1枚足りないのでも 0.5% しかない.

46種類の 4枚ずつ(sim(46,88,4,1000000))も,全部揃ったのは 235回で 1枚足りないのが 2957回.なので,1枚足りないのは 0.3% 程度.

ということで,今回の「R1 側は揃った.R2側は 1枚足りないだけだった」になる確率は 0.05% * 0.3% = 0.00015% 程度で現実的には起こらんという見積もり.なので何か別の要因でカードが揃いやすくなってるはず.

「並んでるパックをがっさり掴んで買ってきた」というのが効いてるのかね.よーわからん.

Home > Archives > 2026年09月24日

Search
Feeds

Page Top