Skip to content

Instantly share code, notes, and snippets.

@f3ath
Last active March 28, 2024 03:34
Show Gist options
  • Save f3ath/fa73c42b74ce4edfa70489efb967b72e to your computer and use it in GitHub Desktop.
Save f3ath/fa73c42b74ce4edfa70489efb967b72e to your computer and use it in GitHub Desktop.
# Birthday paradox simulation. https://en.wikipedia.org/wiki/Birthday_problem
from argparse import ArgumentParser
from random import randint
from typing import Set
from math import factorial
DAYS_IN_YEAR = 365
def main():
parser = ArgumentParser(prog="birthday", description="Birthday Paradox Simulator")
parser.add_argument("-s", "--size", dest="size", help="the group size", default=23, type=int)
parser.add_argument("-e", "--experiments", dest="experiments", help="number of experiments to run", default=1000,
type=int)
args = parser.parse_args()
size = args.size
experiments = args.experiments
print(f'Simulating Birthday Paradox with group size {size}, {experiments} experiments')
print(f'Computed: {compute(size)}')
print(f'Simulated: {simulate(experiments, size)}')
# Generates `num` random uniformly distributed birthdays.
# Returns the set of unique birthdays
def generate_birthdays(num: int) -> Set[int]:
days: Set[int] = set()
for _ in range(num):
days.add(randint(1, DAYS_IN_YEAR))
return days
def simulate(experiments: int, size: int) -> float:
dupes = 0
for _ in range(experiments):
if len(generate_birthdays(size)) < size:
dupes = dupes + 1
return dupes / experiments
# Computes the probability of a duplicate birthday for the group of the given `size`
def compute(size: int):
return 1 - factorial(DAYS_IN_YEAR) / (DAYS_IN_YEAR ** size * factorial(DAYS_IN_YEAR - size))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment