Riddler Express
Help, thereβs a cricket on my floor! I want to trap it with a cup so that I can safely move it outside. But every time I get close, it hops exactly foot in a random direction.
I take note of its starting position and come closer. Boom β it hops in a random direction. I get close again. Boom β it takes another hop in a random direction, independent of the direction of the first hop.
What is the most probable distance between the cricketβs current position after two random jumps and its starting position? (Note: This puzzle is not asking for the expected distance, but rather the most probable distance. In other words, if you consider the probability distribution over all possible distances, where is the peak of this distribution?)
Solution
Let be the angle between the cricketβs jumps. Using the cosine law, we see that the distance from the center to the end point of the second hop is . The least distance from the starting point is and the maximum distance is . We can asssume that .
For any real , we have the CDF of ,
Taking the derivative of the CDF, the PDF of is on .
The PDF approaches infinity as , therefore the most probable distance is feet.
Computational solution
From the histogram below, we see that the most probable distance is indeed feet.
import numpy as np
from math import pi, sqrt, sin, cos
import matplotlib.pyplot as plt
def distances(num_samples = 1000000):
def dist(row):
return sqrt((cos(row[0])-cos(row[1]))**2 + (sin(row[0])-sin(row[1]))**2)
angles = np.random.uniform(0, 2*pi, (num_samples,2))
return np.apply_along_axis(dist, 1, angles)
def plot_dist_hist(distances):
plt.hist(distances, bins='auto')
plt.xlabel('Distance')
plt.ylabel('Frequency')
plt.title('Distance from the starting point')
plot_dist_hist(distances())
Riddler Classic
When you roll a pair of fair dice, the most likely outcome is (which occurs 1/6 of the time) and the least likely outcomes are and (which each occur of the time).
Annoyed by the variance of these probabilities, I set out to create a pair of βuniform dice.β These dice still have sides that are uniquely numbered from to , and they are identical to each other. However, they are weighted so that their sum is more uniformly distributed between and than that of fair dice.
Unfortunately, it is impossible to create a pair of such dice so that the probabilities of all sums from to are identical (i.e., they are all ). But I bet we can get pretty close.
The variance of the probabilities is the average value of the squared difference between each probability and the average probability (which is, again, ). One way to make my dice as uniform as possible is to minimize this variance.
So how should I make my dice as uniform as possible? In other words, which specific weighting of the dice minimizes the variance among the probabilities? That is, what should the probabilities be for rolling or with one of the dice?
Computational Solution
Let be the probabilities for rolling or with one of the dice. We have and for . To calculate the variance among the probabilities, we first need to calculate for . The probabilities are fairly straightforward to calculate e.g.
The variance is then given by
From the code below we see that the minimum value of the variance is and the probabilities are , , , , and .
from scipy.optimize import minimize
def variance(probs):
prob_sums={}
for d1,d2 in [(i,j) for i in range(6) for j in range(6)]:
prob_sums[d1+d2] = prob_sums.get(d1+d2, 0) + probs[d1]*probs[6+d2]
return sum([(p - 1/11)**2 for p in prob_sums.values()])/11
minimize(variance, [0.5]*12, constraints=[{'type':'eq', 'fun':lambda probs:sum(probs[:6])-1},
{'type':'eq', 'fun':lambda probs:sum(probs[6:])-1}])
If we allow the two dice to have different weightings, we can do much better.From the code below we see that the minimum value of the variance is and the probabilities are , , , , and for the first die and , , , , and for the second.
minimize(variance, [0.5]*12, bounds=[(0,1)]*12,
constraints=[{'type':'eq', 'fun':lambda probs:sum(probs[:6])-1},
{'type':'eq', 'fun':lambda probs:sum(probs[6:])-1},
{'type':'eq', 'fun':lambda probs:probs[0]-0.5}])