Skip to content

Instantly share code, notes, and snippets.

@jejones3141
Last active January 3, 2020 03:08
Show Gist options
  • Save jejones3141/d05687912c85bf859987a1f02dfe0ee0 to your computer and use it in GitHub Desktop.
Save jejones3141/d05687912c85bf859987a1f02dfe0ee0 to your computer and use it in GitHub Desktop.
solution to 09/20/19 Riddler Express--it's like the 10/12/18 Riddler Classic, just changing the function we're looking for a zero of.
import math
from scipy.optimize import brentq
import scipy.integrate as integrate
import matplotlib.pyplot as plt
# Solve the 09/20/19 Riddler Express problem on fivethirtyeight.com.
# This is much like the 10/12/18 Riddler Classic problem with the goatn
# and the circular pen; perhaps the new Riddler thinks it not all that
# hard, especially with the earlier problem as a guide.
#
# The problem: overlap two discs D1 and D2 of equal radius symmetrically
# so that the areas of D1 \ D2, D2 \ D1, and D1 ∩ D2 are all equal.
#
# So, let's place D1 and D2 in the plane.
#
# WLOG...
# 1. let's give them radius 1 (specified in the problem statement).
# 2. If d is the distance between the centers, let's put them on the plane
# such that the centers are at (-d/2, 0) and (d/2, 0), so they're symmetric
# around the X-axis.
#
# Clearly d must be greater than 0 and less than 2.
#
# Given that, note that the circles bounding the discs are precisely those
# you draw to construct the perpendicular bisecotor of the segment joining
# the centers, and therefore that perpendicular bisector is the Y-axis. They're
# symmetric about the Y-axis, too.
#
# From that symmetry, clearly we need only assure that the portions of the
# regions above the X-axis have equal area. If we just look at the first
# quadrant, we can see that it should suffice to show that the part of the
# intersection in the first quadrant has half the area of the other part.
#
# It turns out that to let everything be done with the same function to
# integrate, it's better to find the area of the entire region in the first
# quadrant and check that the area of the portion of the intersection is
# one-third of that. (That's trivially equivalent to the previous condition.)
#
# Once the smoke clears, the area of the whole first quadrant hunk is the
# integral from -d/2 to 1 of sqrt(1 - x^2) dx
# and that of the portion of the intersection in the first quadrant is the
# integral from d/2 to 1 of sqrt(1 - x^2) dx
#
# We'll pass on https://www.integral-calculator.com/ and use scipy.integrate
# this time--we really should have done that for the goat problem, too;
# it's not all that much slower, and clearer to the reader. That gets us back
# to scipy.optimize.brentq again.
# For a given choice of d, return the difference between the area of the first
# quadrant region as a whole and three times that of the portion of the
# intersection in the first quadrant.
def delta(d):
def circleY(x): return math.sqrt(1 - x**2)
firstQuadWhole, err1 = integrate.quad(circleY, -d / 2, 1)
firstQuadIntersect, err2 = integrate.quad(circleY, d / 2, 1)
return firstQuadWhole - 3 * firstQuadIntersect
def centerSeparation():
return brentq(delta, 0.2, 1.8)
# Plot the solution.
def plotsoln():
d = centerSeparation()
fig, ax = plt.subplots()
ax.add_artist(plt.Circle((-d / 2, 0), 1, color='#f0000060'))
ax.add_artist(plt.Circle((d / 2, 0), 1, color='#0000f060'))
plt.grid(True)
plt.xlim(-(1 + d / 2) - 0.25, 1 + d / 2 + 0.25)
plt.ylim(-1.25, 1.25)
plt.title('solution to 9/20/19 Riddler Express: d={0:.5f}'.format(d))
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment