Skip to content

Instantly share code, notes, and snippets.

@dliggat
Created Oct 13, 2013
Embed
What would you like to do?
Simulating the birthday paradox.
#!/usr/bin/env ruby
require 'optparse'
def parse_options
options = { }
OptionParser.new { |opts|
opts.banner = "Usage: #{__FILE__} --group-size G --trial-count T"
opts.on('-g', '--group-size size', 'Size of the group') { |v| options[:group_size] = v }
opts.on('-t', '--trial-count count', 'How many trials to run') { |v| options[:trial_count] = v }
}.parse!
raise OptionParser::MissingArgument.new if [:group_size, :trial_count].any? { |v| options[v].nil? }
options
end
def to_percentage(numer, denom)
decimal = numer.to_f / denom
(decimal * 100).round(4).to_s + '%'
end
def shared_birthday?(group_size)
# Generate an array with size `group_size`, and randomly assign every member a birthday.
# Return true if two members share a birthday; else return false.
counter = Hash.new 0
birthdays = group_size.times.map { rand 365 }
birthdays.each do |birthday|
counter[birthday] += 1
return true if counter[birthday] > 1
end
false
end
def run_birthday_trials(group_size, trial_count)
# Run the shared_birthday? experiment `trial_count` times.
# Return the number of experiments which resulted in a shared birthday.
successes = 0
trial_count.times { successes += 1 if shared_birthday? group_size }
successes
end
if __FILE__ == $0
options = parse_options
group_size = options[:group_size].to_i
trial_count = options[:trial_count].to_i
successes = run_birthday_trials group_size, trial_count
puts <<-EOS.gsub!(/^ +/, '')
Using a group size of #{group_size} people, in #{trial_count} independent trials, at least
two people shared a birthday in #{successes} of those trials.
In other words, within a group of #{group_size} people, the probability that two people share
a birthday is #{to_percentage successes, trial_count}.
EOS
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment