Python
"""
The Birthday Paradox is the surprisingly high probability that two people will have the same birthday even in a small group of people.
In a group of 70 people, there’s a 99.9 percent chance of two people having a matching birthday. 
But even in a group as small as 23 people, there’s a 50 percent chance of a matching birthday. 

This program performs several probability experiments to determine the percentages for groups of different sizes. 
"""

import random
from typing import Final
# optional: a qualifier we'll use to prevent edits or accidental changes to one
# of our variables

def generate_birthday():
    """Generate a random birthday in the format str('Mon Day')."""
    month = [
        "Jan",
        "Feb",
        "Mar",
        "Apr",
        "May",
        "Jun",
        "Jul",
        "Aug",
        "Sep",
        "Oct",
        "Nov",
        "Dec",
    ]
    month_selection = month[random.randint(0, 11)]

    match month_selection:
        case "Feb":
            day_selection = random.randint(1, 29)
        case "Apr" | "Jun" | "Sep" | "Nov":
            day_selection = random.randint(1, 30)
        case "Jan" | "Mar" | "May" | "Jul" | "Aug" | "Oct" | "Dec":
            day_selection = random.randint(1, 31)

    return str(month_selection) + " " + str(day_selection)


def print_birthdays(num_of_bdays):
    """Generate the number of requested birthdays to terminal."""
    arr_bday = []
    print(f"Here are {num_of_bdays} birthdays:")
    while num_of_bdays > 0:
        bday = generate_birthday()
        arr_bday.append(bday)
        print(bday, end=", ")
        num_of_bdays -= 1
    return arr_bday


def simulate_birthdays(num_of_sims):
    """Runs generate_birthday by number of simulations count"""
    arr_sim_bday = []
    for _ in range(0, num_of_sims):
        arr_sim_bday.append(generate_birthday())
    return arr_sim_bday


def calculate_birthdays(bday_data, sim_bday_data):
    """Check for matching birthdays in the simulated data."""
    matching_data_count = 0
    for num in range(NUMBER_OF_SIMULATIONS): # 0 -> 100,000
        if sim_bday_data[num] in bday_data:
            matching_data_count += 1
    return matching_data_count

no_user_input = True

while no_user_input:
    prompt_num = int(input("How many birthdays shall I generate? "))
    if prompt_num > 100 or prompt_num <= 0:
        print("Out of range, please enter in a number.")
    else:
        no_user_input = False

NUMBER_OF_SIMULATIONS = 100000
generated_birthdays = print_birthdays(prompt_num)
simulated_birthdays = simulate_birthdays(NUMBER_OF_SIMULATIONS)
matching_birthdays_count: Final = calculate_birthdays(generated_birthdays, simulated_birthdays)

print(f"\n\nGenerating {prompt_num} random birthdays {NUMBER_OF_SIMULATIONS} times...")
print(f"Out of {NUMBER_OF_SIMULATIONS} simulations of {prompt_num} birthdays, there was a matching birthday in that group {matching_birthdays_count} times.")
percentage = float((matching_birthdays_count / NUMBER_OF_SIMULATIONS) * 100)
percentage = round(percentage, 3)
print(f"This means that {prompt_num} people have a {percentage} % chance of having a birthday in their group.")

# End-of-file (EOF)