Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Last active January 16, 2017 07:18
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 JoshCheek/e26857438361cbab07fb7e73af83c47c to your computer and use it in GitHub Desktop.
Save JoshCheek/e26857438361cbab07fb7e73af83c47c to your computer and use it in GitHub Desktop.
If you put 23 people in a room, 2 of them probably have the same birthday
# inspired by http://www.smbc-comics.com/comic/monty-hall-problems
SAMPLES = 50_000
DAYS = 365
PRECISION = 4
def prob_of_same_bday(num_people)
SAMPLES.times.count { share_bday_in_room_of_size? num_people } / SAMPLES.to_f
end
def share_bday_in_room_of_size?(num_people)
bdays = Array.new DAYS, 0 # number of people born on the given day, index 0 ≈ 1 Jan, DAYS-1 ≈ 31 Dec
num_people.times.any? { (bdays[rand DAYS] += 1) == 2 }
end
def calculate_probability(num_people)
1 - num_people.times.reduce(1.0) { |p, n| p * (DAYS-n) / DAYS }
end
def answer?(num_people)
calculate_probability(num_people) > 0.5 &&
calculate_probability(num_people-1) < 0.5
end
# Using 1+DAYS as the upper bound because: by the pigeonhole principle,
# we know that there is a 100% chance of two people sharing a birthday
# when there are more people than days. Eg: if there are 10 days in a year,
# and 11 people in a room, it is guaranteed that at least 2 of them share a birthday.
NUM_PEOPLE = 1.upto(1+DAYS).find do |n|
p = prob_of_same_bday(n).round(PRECISION)
n # => 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23
p # => 0.0, 0.0025, 0.0081, 0.0178, 0.0286, 0.0403, 0.0569, 0.0733, 0.0971, 0.1159, 0.1381, 0.1664, 0.1948, 0.2237, 0.2534, 0.2806, 0.3171, 0.3495, 0.3815, 0.4103, 0.4426, 0.4733, 0.5059
p > 0.5
end
# Calculated results:
NUM_PEOPLE # => 23
prob_of_same_bday NUM_PEOPLE # => 0.5097
# Validate results:
calculate_probability NUM_PEOPLE # => 0.5072972343239855
answer? NUM_PEOPLE # => true
answer? NUM_PEOPLE-1 # => false
answer? NUM_PEOPLE+1 # => false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment