Coding Short: Meeting in a Bar

Theodore Yoong
4 min readJan 13, 2019

--

I’ve been studying for trading internship interviews for a while now, which are notorious for testing probability and statistics problems. Of the problems I’ve encountered, this is definitely one of my favourites:

Two people arrive at a bar between 8:00 PM and 9:00 PM. They stay for thirty minutes before leaving. If the arrival time for each person is uniformly distributed, calculate the probability they meet in the bar.

Suppose we scale the times back to 0 and 60 (in units of minutes). We also let the arrival times of the two people be X and Y (and for brevity, the people themselves), both of which are independent and identically distributed random variables with common distribution Unif(0,60).

For the two people to meet, X must arrive before Y leaves, so X<Y+30. Y must also arrive before X leaves, so Y<X+30. This can be succinctly described by the single condition |X-Y|<30.

The beautiful thing about this problem is that it can be solved geometrically. For someone like me whose visual-spatial abilities aren’t the most sharp, what better way to graph the probabilities out, than to code it out in Python?

The only libraries required are numpy and matplotlib.pyplot.

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

We use np.random.uniform to draw samples from a uniform distribution. We also use np.where to filter out the samples which satisfy the condition abs(x-y)<30. Those which satisfy are the condition are coloured red in our scatterplot, and those which do not are coloured blue.

samples = 500000
x, y = np.random.uniform(0, 60, samples), np.random.uniform(0, 60, samples)
colours = np.where(abs(x-y)<30, 'r', 'b')
s = 0
for element in colours:
if element == 'r':
s += 1
print("Probability of meeting is {}.".format(s/samples))
plt.scatter(x, y, c=colours, s=1)
plt.show()

This outputs:

Probability of meeting is 0.74995.

This makes calculating the probability much easier! The area of the two triangles is 30×30 and the area of the entire plot is 60×60, and thus the probability is (60×60–30×30)/(60×60)=3/4, which is very close to the empirical probability from our simulation!

I also attempted two slight variants of the problem. The first variant reads:

If one person arrives randomly between 8:00 PM and 8:45 PM, staying for 30 minutes before leaving, and the other person arrives randomly between 8:30 PM and 9:00 PM, staying for 15 minutes before leaving, what is the probability they meet?

This time, we let X~Unif(0,45) and Y~Unif(30,60). Additionally, the two conditions we must meet are X<Y+15 (X arrives before Y leaves) and Y<X+30 (Y arrives before X leaves). The modified code for this problem is:

samples = 500000
x, y = np.random.uniform(0, 45, samples), np.random.uniform(30, 60, samples)
colours = np.where(np.logical_and(x<y+15, y<x+30), 'r', 'b')s = 0
for element in colours:
if element == 'r':
s += 1
print(“Probability of meeting is {}.”.format(s/samples))
plt.scatter(x, y, c=colours, s=1)
plt.show()

This outputs:

Probability of meeting is 0.66703.

This time, the probability is (30×45–30×15)/(30×45)=2/3, which is once again close to what we our simulation calculated.

The other variant reads:

If instead, each person spends exactly fifteen consecutive minutes between 8:00 PM and 9:00 PM in the bar, what is the new probability of meeting?

Clearly, the two people cannot arrive after 8:45 PM as they must spend exactly fifteen minutes in the bar. There is hence a “forbidden region” which is outside the sample space for our problem. The rest is exactly the same (each person arrives before the other leaves), with the condition |X-Y|<15.

Calculating the probability for this problem is identical to the original problem for X and Y both distributed on Unif(0,45) with condition |X-Y|<15, which is 5/9. However, for the purposes of visualising the “forbidden region”, the modified code for this variant includes a second np.where condition, which colours this region yellow.

samples = 500000
x, y = np.random.uniform(0, 60, samples), np.random.uniform(0, 60, samples)
colours = np.where(np.logical_and(abs(x-y)<15, np.logical_and(x<45, y<45)), 'r', (np.where(np.logical_and(x<45, y<45), 'b', 'yellow')))s, t = 0, 0
for element in colours:
if element == 'r':
s += 1
t += 1
elif element == 'b':
t += 1
print("Probability of meeting is {}.".format(s/t))
plt.scatter(x, y, c=colours, s=1)
plt.show()

This time, this outputs:

Probability of meeting is 0.5567216143242859.

This concludes my analysis on the problem. Feel free to leave any feedback!

--

--