Can You Win the Collaborative Card Game?
This Week's Fiddler
If we pair up each card from one 52-card deck with another, we lose if any of them in the same position match. In other words, we win if one deck is a derangement of the other!
Let denote the -th derangement number (also known as the -th subfactorial). There are derangements of the deck out of possible permutations of the deck.
Thus, the chance of winning is . This comes out to , or about 36.79%.
Answer: (!52)/(52!), or ~36.79% (193937806586896328746924473226467394949530139620339174273819171217/527177615496365219422618541545122659969212453861982208000000000000)
Extra Credit
In this version of the game, we're combining the decks, shuffling the cards, and forming card pairs, hoping to never get a matching pair.
Let be the number of matching pairs left, let be the number of unmatched (single) cards left, and let be the probability we win given matching pairs of cards and unmatched cards left in the deck.
If there are no cards left, then we have won, so . Also, and should never be negative, so if or . Otherwise, let's consider the three successful events with drawing two cards: () two cards are chosen from different pairs, () one card is chosen from a pair and one is a single, or () both cards are singles.
(Note: We can also confirm that the probability that we lose, meaning a match is of the same pair, is , adding up with , , and to make 1. These four events are thus exhaustive possibilities.)
For , we convert two pairs into two unmatched singles, so the next step is . For , we convert one pair into an unmatched single but also consume a different unmatched single, netting in zero change to the number of singles and making the next step . For , we simply consume two unmatched singles: .
Putting it all together then, when and and at least one of or is positive:
Now that we have a recursive formula defined, we can convert it into Python code (with dynamic programming to cache results):
from functools import cache
@cache
def prob(pairs=52, singles=0):
if pairs < 0 or singles < 0:
return 0
if pairs == 0 or singles == 0:
return 1
total = pairs * 2 + singles
return (
# Two cards from different pairs
prob(pairs - 2, singles + 2) * Fraction(4 * pairs * (pairs - 1), total * (total - 1))
# One card from a pair and one single
+ prob(pairs - 1, singles) * Fraction(4 * pairs * singles, total * (total - 1))
# Two singles
+ prob(pairs, singles - 2) * Fraction(singles * (singles - 1), total * (total - 1))
)
print(prob())
print(float(prob()))
Output:
335561727225862936774353972738829595013743745454800896090990716254443717947031552/555926557447585078813889409645210912590669690718980253197612210789777133544921875
0.6036080175167761
Looks like our odds have improved to , or about 60.36%.
Answer: ~60.36% (335561727225862936774353972738829595013743745454800896090990716254443717947031552/555926557447585078813889409645210912590669690718980253197612210789777133544921875)
Simulation
Python simulation code to check my work:
import random
N = 52
T = 10**7
# This Week's Fiddler
random.seed(12)
total = 0
deck1 = list(range(N))
deck2 = list(range(N))
for _ in range(T):
random.shuffle(deck1)
random.shuffle(deck2)
total += all(a != b for a, b in zip(deck1, deck2))
print('Part 1 simulated probability:', total / T)
# Extra Credit
random.seed(12)
total = 0
deck = list(range(N)) + list(range(N))
for _ in range(T):
random.shuffle(deck)
total += all(a != b for a, b in zip(deck[:N], deck[N:]))
print('Part 2 simulated probability:', total / T)
Output:
Part 1 simulated probability: 0.3678149
Part 2 simulated probability: 0.6032972