Books · The Fiddler: Solutions
Chapter 56
How Many Rides Can You Reserve?
A theme park has one-hour ride slots ( a.m. to p.m.). You reserve rides in distinct random slots. After completing each ride you reserve one more, in a uniformly random slot after your latest scheduled ride. You stop once a ride lands in the final (– p.m.) slot. On average, how many rides do you get?
The Fiddler, Zach Wissner-Gross, May 2, 2025(original post)
Solution
Each new reservation pushes your latest slot forward to a uniform choice in , and you stop when . So the number of extra rides beyond the first three is the number of forward jumps from your starting maximum to . Let be that expected number of jumps: The total is , averaged over of three distinct random slots:
The computation
Build exactly from its recurrence (each value depends only on later slots), then average over every starting triple of slots.
from fractions import Fraction as F
from itertools import combinations
f = {12: F(0)}
for m in range(11, 0, -1):
f[m] = 1 + sum(f[k] for k in range(m + 1, 13)) * F(1, 12 - m)
num = sum(f[max(s)] for s in combinations(range(1, 13), 3))
print(3 + num / F(220)) # 118361/27720
Extra Credit
Now each new reservation goes in a random available slot after the ride you just completed (not after your latest), and you continue until no slots remain. On average, how many rides now?
Solution
Reservations can now slot in between existing rides, so the schedule fills up far more. Simulating the process, (The source’s value is paywalled; this is my own simulation.)
The computation
Run the booking process itself: keep a set of scheduled slots, advance to the next one after the current ride, and after each ride book a random still-free slot beyond it until none remain.
import random
def run(rng):
sched = set(rng.sample(range(1, 13), 3)); done = cur = 0
while True:
nxt = min((s for s in sched if s > cur), default=None)
if nxt is None: break
done += 1; cur = nxt
avail = [s for s in range(cur + 1, 13) if s not in sched]
if avail: sched.add(rng.choice(avail))
return done
rng = random.Random(5)
print(round(sum(run(rng) for _ in range(600_000)) / 600_000, 3)) # ~6.81