争夺王牌
Race to Ace
题目详情
在看到第一张 A 之前,你需要从 52 张牌中抽出多少张牌?
What is the expected number of cards you need to draw from a 52-card deck before you see the first ace?
解析
假设你有以下设置:
其中 代表 Ace,间隙代表它们之间的牌。
有 卡可放入 间隙中,因此每个间隙的预期卡数为 。从第一个间隙中挑选出所有牌后,你挑选的下一张牌将是 A,因此在获得 A 之前我们挑选的牌的预期数量为
import random
from typing import Tuple
from itertools import product
suits = ['S', 'C', 'D', 'H']
ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
class Deck:
def __init__(self) -> None:
"""Initialize a deck of cards"""
self.cards = [(rank, suit) for rank, suit in product(ranks, suits)]
def shuffle(self) -> None:
"""Shuffle a deck of cards"""
self.cards = random.sample(self.cards, 52)
def draw(self) -> Tuple[str, str]:
"""Draw a card from the deck"""
return self.cards.pop()
def isEmpty(self) -> bool:
"""Check if the deck has cards"""
return self.cards == []
def simulation() -> int:
deck = Deck()
deck.shuffle()
cards_drawn = 0
# Keep drawing until we find an ace
while not deck.isEmpty():
suit, rank = deck.draw()
cards_drawn += 1
if suit == "A":
return cards_drawn
return cards_drawn
cards_needed = [simulation() for _ in range(10_000)]
# Get the expected number of cards until we draw our first ace
print(sum(cards_needed) / len(cards_needed))Original Explanation
Imagine you have the following setup:
Where represents the Ace and the gaps represent the cards in between them.
There are cards to place into the gaps, thus the expected number of cards per gap is . After picking all the cards from the first gap, the next card you pick would be an ace so the expected number of cards we pick until we get an ace is
import random
from typing import Tuple
from itertools import product
suits = ['S', 'C', 'D', 'H']
ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
class Deck:
def __init__(self) -> None:
"""Initialize a deck of cards"""
self.cards = [(rank, suit) for rank, suit in product(ranks, suits)]
def shuffle(self) -> None:
"""Shuffle a deck of cards"""
self.cards = random.sample(self.cards, 52)
def draw(self) -> Tuple[str, str]:
"""Draw a card from the deck"""
return self.cards.pop()
def isEmpty(self) -> bool:
"""Check if the deck has cards"""
return self.cards == []
def simulation() -> int:
deck = Deck()
deck.shuffle()
cards_drawn = 0
# Keep drawing until we find an ace
while not deck.isEmpty():
suit, rank = deck.draw()
cards_drawn += 1
if suit == "A":
return cards_drawn
return cards_drawn
cards_needed = [simulation() for _ in range(10_000)]
# Get the expected number of cards until we draw our first ace
print(sum(cards_needed) / len(cards_needed))