素数大富豪というトランプゲームが流行っているらしい。
公式ルール
主なルール
- n枚の手札(ルールにより異なるが7や11などの素数枚が多いらしい)を先に無くした人が勝ち
- 場に素数を出していく
- 10と3で103というように2枚出し、3枚出し……と任意の枚数を出すことが可能
従って、初手ですべてのカードを出して勝つことも可能らしい。
(なお、私は実際にプレイしたことがほとんどないためルールの認識が間違っているかもしれない……)
ということで確認する。
素数を作れない自明なパターン
- 全てのカードが偶数または5
- どのように並べ替えても2の倍数または5の倍数となる
- 全てのカードの和が3の倍数
- どのように並べ替えても3の倍数となる
検証ソース
def is_prime(n):
"""試し割りによる素数判定"""
assert(isinstance(n, int))
assert(n > 0)
if n == 1:
return False
if n == 2:
return True
divisor = 2
while divisor ** 2 <= n:
if n % divisor == 0:
return False
divisor += 1
return True
def is_all_even_or_five(tefuda):
return all([x % 2 == 0 or x == 5 for x in tefuda])
def is_three_multiple(tefuda):
return sum(tefuda) % 3 == 0
import random
from collections import defaultdict
result_dict = defaultdict(int)
def can_zendashi(tefuda, precision=10000):
if is_all_even_or_five(tefuda):
result_dict['全部偶数か5'] += 1
return False
if is_three_multiple(tefuda):
result_dict['3の倍数'] += 1
return False
for _ in range(precision):
# 適当に並べ替えて素数かどうか判定する
random.shuffle(tefuda)
num = int(''.join(list(map(str, tefuda))))
if is_prime(num):
result_dict['素数'] += 1
return True
result_dict['たぶん無理'] += 1
return False
適当に1000回ほど回してみた。
{'素数': 678, '全部偶数か5': 8, '3の倍数': 314}
結論
かなり雑に検証したが、およそ2/3の確率で(理論上)ワンターンキルできてしまう。
ジョーカーや山札から手札に加える行為を考慮していないため、上記の確率はさらに上がりそう。