Books · The Fiddler: Solutions
Chapter 36
Can You Take a “Risk”?
A Risk deck has territory cards: infantry, cavalry, and artillery. You are dealt three cards at random. You may trade them in if they are all the same kind or all three different kinds. What is the probability you can trade in?
The Fiddler, Zach Wissner-Gross, September 26, 2025(original post)
Solution
Out of equally likely hands, the tradeable ones are “all the same” ( ways) or “all different” ( ways, one of each kind):
The computation
Build the -card deck and run through every three-card hand, counting those that are all one kind or all three kinds. The exact fraction is .
from itertools import combinations
from math import comb
from fractions import Fraction as F
deck = [k for k in range(3) for _ in range(14)] # 14 each of 3 kinds
tradeable = lambda h: len(set(h)) in (1, 3) # all same, or all different
good = sum(tradeable(h) for h in combinations(deck, 3))
print(F(good, comb(42, 3))) # 137/410
Extra Credit
Now add two wildcards (each can stand for any kind), making cards. Drawing one at a time, how many cards on average until you first hold three you can trade in? (It is between and , and it is not .)
Solution
A wildcard plus any two cards is always tradeable, so a non-tradeable hand contains no wildcard. With always and always, (The source’s value is paywalled; this exact figure is my own.)
The computation
Deal from the real -card deck (two wildcards included), drawing one at a time until some three of the cards in hand form a tradeable set, and average the draw count over millions of shuffles.
import numpy as np
from collections import Counter
deck = np.array([0]*14 + [1]*14 + [2]*14 + [3, 3]) # kind 3 = wildcard
def has_triple(h):
cnt = Counter(h)
return (cnt[3] >= 1 and len(h) >= 3 # wildcard plus any two
or any(cnt[k] >= 3 for k in (0, 1, 2)) # three of a kind
or (cnt[0] and cnt[1] and cnt[2])) # one of each kind
rng = np.random.default_rng(0); M = 2_000_000; total = 0
for _ in range(M):
rng.shuffle(deck); h = []
for card in deck:
h.append(int(card))
if len(h) >= 3 and has_triple(h): break
total += len(h)
print(round(total / M, 4)) # ~3.760