78 lines
1.9 KiB
Python
Executable file
78 lines
1.9 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
|
|
import random, datetime, os, math, decimal
|
|
|
|
MAX_SIMULATIONS = 100_000
|
|
|
|
class ProgressBar:
|
|
def __init__(self, size=100, prompt=None):
|
|
self.size = size
|
|
self.prompt = prompt
|
|
self.at = 0
|
|
self.columns = os.get_terminal_size().columns
|
|
self.space = self.columns - 9
|
|
self.percent = None
|
|
self.moved = None
|
|
|
|
if self.prompt is not None:
|
|
self.space -= len(self.prompt) + 1
|
|
|
|
decimal.getcontext().prec = 4
|
|
|
|
def move(self, amt=1):
|
|
self.at += amt
|
|
self.percent = decimal.Decimal.from_float(self.at / self.size)
|
|
self.moved = math.floor(self.space * self.percent)
|
|
|
|
def render_bar(self):
|
|
return ("\u2588" * self.moved) + (" " * (self.space - self.moved))
|
|
|
|
def progress(self):
|
|
percent = self.percent * 100
|
|
|
|
if percent.compare(decimal.Decimal(100)) == decimal.Decimal(-1):
|
|
return f"{percent:05.2f}"
|
|
else:
|
|
return f"{percent:.1f}"
|
|
|
|
def render(self):
|
|
if self.prompt is not None:
|
|
return f"{self.prompt} [{self.render_bar()}] {self.progress()}%"
|
|
else:
|
|
return f"[{self.render_bar()}] {self.progress()}%"
|
|
|
|
def __str__(self):
|
|
return self.render()
|
|
|
|
count = int(input(f"Total birthdays: "))
|
|
matches = 0
|
|
prog_bar = ProgressBar(size=MAX_SIMULATIONS, prompt="Running simulations")
|
|
|
|
for simulation in range(MAX_SIMULATIONS):
|
|
birthdays = { }
|
|
|
|
for idx in range(count):
|
|
year = datetime.date(2001, 1, 1)
|
|
days = datetime.timedelta(random.randint(0, 364))
|
|
birthday = year + days
|
|
|
|
if birthday in birthdays:
|
|
matches += 1
|
|
break
|
|
else:
|
|
birthdays[birthday] = 0
|
|
|
|
prog_bar.move(1)
|
|
end = ""
|
|
|
|
if simulation == MAX_SIMULATIONS - 1:
|
|
end = "\n"
|
|
|
|
print(f"\r{prog_bar}", end=end)
|
|
|
|
percent = decimal.Decimal.from_float(matches / MAX_SIMULATIONS) * 100
|
|
|
|
if matches == MAX_SIMULATIONS:
|
|
print(f"Calculated {percent:.1f}% people shared a birthday.")
|
|
else:
|
|
print(f"Calculated {percent:05.2f}% people shared a birthday.")
|