Skip to content

Instantly share code, notes, and snippets.

@mreid-moz
Created June 19, 2018 15:17
Show Gist options
  • Save mreid-moz/2c99083e92cc615daaf3f7d268d66a49 to your computer and use it in GitHub Desktop.
Save mreid-moz/2c99083e92cc615daaf3f7d268d66a49 to your computer and use it in GitHub Desktop.
Like the birthday paradox, but for banking PINs. How many people should it take before you expect a duplicate PIN?
import random
### Converging on 124.908224 after 125000 iterations
iterations = 0
total_pins = 0
max_pin = 9999
bucket_count = max_pin / 10
histogram = [0] * bucket_count
bucket_size = max_pin / bucket_count
max_bucket_count = 0
def stars(n):
return "".join(['*'] * n)
def normalize(v, n, max_v):
return int(((float(v) / float(max_v)) * n))
def display(h, bs, c):
for i, b in enumerate(h):
if b > 10:
print("{:>10}: {}".format(i * bs, stars(normalize(b, 20, c))))
while True:
iterations = iterations + 1
pins = set()
for endpoint in range(max_pin):
next_pin = random.randint(0, max_pin)
if next_pin in pins:
#print "Found a double of {} after {} iterations.".format(next_pin, endpoint)
break
else: pins.add(next_pin)
#print "endpoint was {}".format(endpoint)
total_pins += endpoint
histogram[endpoint / bucket_size] += 1
if histogram[endpoint / bucket_size] > max_bucket_count:
max_bucket_count = histogram[endpoint / bucket_size]
if iterations % 5000 == 0:
display(histogram, bucket_size, max_bucket_count)
print "Converging on {} after {} iterations".format(float(total_pins) / float(iterations), iterations)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment