Library · The Fiddler: Solutions · Chapter 144
How Likely Is a Lopsided League?
Fiddler League Baseball has six divisions of five teams each. Suppose each team’s winning percentage is chosen uniformly at random between and percent, independently of every other team. What is the probability that every team in the East division has a higher winning percentage than every team in the Central division?
The Fiddler, Zach Wissner-Gross, September 15, 2023(original post)
The official solution appeared in the post of September 22, 2023 and gives for the main puzzle and percent for the Extra Credit. Both agree with the answers below.
Solution
The actual percentages do not matter, only their order. Two teams tie with probability zero, so the ten teams of the two divisions finish in some order from best to worst, and since the percentages are independent and identically distributed, all orders are equally likely.
Now forget which team is which and keep only the division: write E for an East team and C for a Central team, and read the ten teams from best to worst. Each order of the ten teams gives a string of five Es and five Cs, and every string arises from exactly orders (shuffle the Es among themselves and the Cs among themselves). So all strings are equally likely too. There are of them, and East is wholly above Central for just one, EEEEECCCCC.
The computation
The program builds the ranking one team at a time, from the top. At each step the next team is equally likely to be any team not yet placed, which is exactly what a random order means. It tracks only how many teams of each division have been placed, and adds up the exact probabilities, with fractions, of all the ways the event can turn out. For the main puzzle the event is decided as soon as either the first Central team is placed (failure, unless East is already complete) or the fifth East team is (success).
from fractions import Fraction
from functools import lru_cache
SIZE = 5 # teams per division
def chance(divisions, verdict):
"""Rank all teams from best to worst, one at a time: the
next team is equally likely to be any team not yet
ranked. counts[d] is how many of division d are ranked so
far; verdict(counts) is 1 or 0 once the event is decided,
None while it is still open. Returns the exact chance."""
@lru_cache(None)
def p(counts):
v = verdict(counts)
if v is not None:
return Fraction(v)
left = divisions * SIZE - sum(counts)
total = Fraction(0)
for d, c in enumerate(counts):
if c < SIZE:
nxt = counts[:d] + (c + 1,) + counts[d + 1:]
total += Fraction(SIZE - c, left) * p(nxt)
return total
return p((0,) * divisions)
def east_over_central(counts):
east, central = counts
if east == SIZE: # East all ranked: did any
return int(central == 0) # Central team come first?
return 0 if central else None
main = chance(2, east_over_central)
print("main:", main, f"= {float(main):.5f}")
It prints
main: 1/252 = 0.00397
Extra Credit
Across all six divisions, what is the probability that there are two divisions such that every team in one has a higher winning percentage than every team in the other?
Solution
A first guess multiplies: there are ordered pairs of divisions, each with chance , giving . That overcounts. When one division sits wholly above another it tends to sit above others too, so the pairs come in clumps, and the clumps are counted several times over.
A cleaner picture comes from thinking of each division as a span: the stretch of percentages from its worst team, , to its best team, . Division lies wholly above division exactly when ’s span starts above the point where ’s ends, . Some pair like this exists exactly when the highest of the six worst-team values is above the lowest of the six best-team values. (The two values must then come from different divisions, since within a single division the worst is below the best.) So the event fails exactly when the highest worst-team value is below every best-team value: when all six spans share a common point.
To find the chance that the spans share a point, look at the division whose worst team is highest; call it , and write that worst-team value as a fraction between and . For this to happen with all spans sharing a point:
one of ’s five teams is at and its other four are above , which has probability density ;
each of the other five divisions has a team below (so ’s worst is the highest) and a team above (so its span reaches ). For one division the chance is , removing the cases all below and all above.
The six choices of give six cases that cannot overlap, so the chance that the spans share a point is The integrand is a polynomial, so this is exact arithmetic. Expand the fifth power as a sum of terms , with and coefficients , multiply each by the factor , and integrate with the standard formula : The sum has terms. The answer is the complement: That is well short of the first guess, as the clumping argument predicted.
The computation
The ranking program from The computation above, now with six divisions. It uses none of the span argument. Reading down the ranking, some division lies wholly above another exactly when one division has all five teams placed while another has none placed yet. The first moment any division is completed settles the matter: if some division has not yet begun, the completed one lies above it; if every division has begun, each one’s best team is already above every division’s worst team, so no division can lie wholly above another.
def some_division_over_another(counts):
if SIZE in counts: # first division completed:
return int(0 in counts) # has some other not begun?
return None
extra = chance(6, some_division_over_another)
print("extra credit:", extra, f"= {float(extra):.6f}")
It prints
extra credit: 2565091/29745716 = 0.086234