Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
My Solution to the December 18th FiveThirtyEight Riddler using Python
from sympy import symbols
from sympy import integrals as Int
from itertools import permutations
class geyser:
'''
This is a python-based solution to the geyser problem presented on
FiveThirtyEight.com. It uses Sympy to evaluate an integral. With that
result, we create a general function for solving with the supplied rates.
'''
def __init__(self, A, B, C):
# Define symbols
self.terms = symbols('x y z')
# Define Rates
self.bounds = [A, B, C]
# Define joint pdf
self.joint_pdf = 1 / (A * B * C)
def set_bounds(self, bounds):
'''
The key to the integration is the bounds.
'''
for i in range(2, 0, -1):
if bounds[i] < bounds[i - 1]:
bounds[i - 1] = bounds[i]
for i in range(2):
if bounds[i] > bounds[i + 1]:
bounds[i] = bounds[i + 1]
return bounds
def uni_integral(self, terms, bounds):
bounds = self.set_bounds(bounds)
return Int.integrate(self.joint_pdf,
(terms[2], terms[1], bounds[2]),
(terms[1], terms[0], bounds[1]),
(terms[0], 0, bounds[0]))
def all_integrals(self):
integrals = []
for p in permutations([0, 1, 2]):
terms = [self.terms[i] for i in p]
bounds = [self.bounds[i] for i in p]
integrals.append(self.uni_integral(terms, bounds))
self.integrals = integrals
def print_sol(self):
collapsed = [self.integrals[i] + self.integrals[i + 1]
for i in range(0, 5, 2)]
self.results = {i[1]: collapsed[i[0]]
for i in enumerate(['A', 'B', 'C'])}
print("P(A < B, C) = ", round(self.results['A'], 4))
print("P(B < A, C) = ", round(self.results['B'], 4))
print("P(C < A, B) = ", round(self.results['C'], 4))
def main():
''' Run fivethirtyeight example '''
# Show the simple solution
my_geyser = geyser(2, 4, 6)
my_geyser.all_integrals()
my_geyser.print_sol()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.