Skip to content

Instantly share code, notes, and snippets.

@lvaughn
Created May 28, 2021 20:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lvaughn/8a3e6fe62b549be0389ae6a21555d510 to your computer and use it in GitHub Desktop.
Save lvaughn/8a3e6fe62b549be0389ae6a21555d510 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# Answer for the 538 Ridder Express for 5/28/21
#
# https://fivethirtyeight.com/features/can-you-crack-the-case-of-the-crystal-key/
N_TEAMS = 30
N_GAMES = 162
EPSILON = 10e-16
def expected_perfect_games(on_base_ptc):
# Find the odds that any one team would throw a perfect game
# Note: Given the constraints, in theory both teams could throw a perfect
# game at the same time, though that is unlikely
odds_perfect_game = (1 - on_base_ptc) ** 27
# The expected value of a binomial distribution is p * N, where
# p is the probability of any given game being perfect, and
# n is the total number of games thrown
return (N_TEAMS * N_GAMES) * odds_perfect_game
# Do a binary search for the correct on base percentage
min_obp = 0.0
max_obp = 1.0
while max_obp - min_obp > EPSILON:
test = (min_obp + max_obp) / 2
expected_value = expected_perfect_games(test)
if expected_value > 1:
min_obp = test
else:
max_obp = test
answer = (min_obp + max_obp) / 2
print(f"Result: {answer} ({expected_perfect_games(answer)})")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment