Last active
March 28, 2024 03:34
-
-
Save f3ath/fa73c42b74ce4edfa70489efb967b72e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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