Books · The Fiddler: Solutions
Chapter 41
How Much Free Money Can You Win?
A casino hands you in free-play vouchers: three vouchers and one voucher. You may wager vouchers (never cash) on an even-money game as often as you like. A winning wager returns the voucher and pays cash equal to its value; a losing wager forfeits the voucher. Vouchers cannot be split. What is the largest amount you can guarantee to walk away with, no matter how the games fall, and how?
The Fiddler, Zach Wissner-Gross, August 15, 2025(original post)
Solution
Hedge. Because each spin has two even-money sides, you can split your vouchers across both and bank the winning side for certain. Solving the game backwards (maximise the worst case over every split of the held vouchers) gives a guaranteed A worst-case-optimal line: first put the voucher on one colour and two vouchers on the other, holding one in reserve. Whichever colour wins, you keep banking cash and re-hedging the survivors; the tightest branch (the side wins, then its successor loses) still nets exactly .
The computation
Encode the hedging game over states (count of s, count of s). For every way to split the held vouchers across the two sides, the adversary picks the worse outcome; you take the split that maximises that worst case. Value iteration converges to the guarantee.
# value iteration over states (a $10s, b $25s); adversarial sides, choose any split.
V = {(a, b): 0 for a in range(4) for b in range(2)}
for _ in range(60):
nv = {}
for a in range(4):
for b in range(2):
best = 0
for ri in range(a+1):
for rj in range(b+1):
for bi in range(a-ri+1):
for bj in range(b-rj+1):
if ri == rj == bi == bj == 0: continue
rc, bc = ri*10 + rj*25, bi*10 + bj*25 # cash on red / black side
best = max(best, min(rc + V[(a-bi, b-bj)], bc + V[(a-ri, b-rj)]))
nv[(a, b)] = best
V = nv
print(V[(3, 1)]) # 35
Extra Credit
With the same vouchers, find a strategy giving at least a chance of winning dollars or more. What is the largest such ?
Solution
Now the coin is fair rather than adversarial, so track the best probability of reaching each cash target and read off the largest target still met with probability . The threshold sits exactly at (The source value is paywalled; this is my own.)
The computation
The same splits, but now each side wins with probability : is the best chance of banking at least more, maximised over splits. Read off the largest target still reaching .
from functools import lru_cache
@lru_cache(None)
def g(a, b, w): # max P(bank >= w more), w in $5 units
if w <= 0: return 1.0
best = 0.0
for ri in range(a+1):
for rj in range(b+1):
for bi in range(a-ri+1):
for bj in range(b-rj+1):
if ri == rj == bi == bj == 0: continue
rc, bc = ri*10 + rj*25, bi*10 + bj*25
best = max(best, .5*g(a-bi, b-bj, w-rc) + .5*g(a-ri, b-rj, w-bc))
return best
print(max(w for w in range(0, 300, 5) if g(3, 1, w) >= 0.5)) # 90