Last active
March 27, 2025 02:28
-
-
Save Krewn/f9fb2e7860126c029fde6de53ea7b615 to your computer and use it in GitHub Desktop.
A questionably stable implementation of random selection by urandom demonstrated with some bingo pulls.
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
| from os import urandom | |
| from math import * | |
| import hashlib | |
| import time | |
| class ___: | |
| pass | |
| _dir = dir(___) | |
| def printSelf(x): | |
| for _ in set(dir(x))-set(_dir): | |
| print(_,":",f'{getattr(x,_)}') | |
| print() | |
| class randomIndexer: | |
| def __init__(self,r = urandom,i = 9001): | |
| self.r = r | |
| self.seti(i) | |
| def seti(self,i): | |
| self.i = i | |
| self.nBytes = ceil(log(i,256)) | |
| self.nBytes = self.nBytes if self.nBytes else 1 | |
| self.extraBits = 8*self.nBytes-ceil(log(i,2)) | |
| def next(self): | |
| randBytes = self.r(self.nBytes) | |
| first = bin(randBytes[0])[self.extraBits+2:] | |
| if len(first) == 0: | |
| first = "0" | |
| randBytes = int.to_bytes(int(first,2))+randBytes[1:] | |
| ans = int.from_bytes(randBytes) | |
| if ans < self.i: | |
| return ans | |
| return self.next() | |
| import itertools | |
| from itertools import product | |
| class bingo: | |
| def __init__(self,balls = ["".join([str(__) for __ in _]) for _ in product([chr(_) for _ in range(48,58)],[chr(_) for _ in range(65,91)])], head = b'ingo'): | |
| self.deck = balls | |
| self.counts = {k:0 for k in self.deck} | |
| self.hand = [] | |
| self.seq = [] | |
| self.ri = randomIndexer(i=len(self.deck)) | |
| def printSeq(self): | |
| return "-".join(self.seq) | |
| def next(self): | |
| #printSelf(self.ri) | |
| i = self.ri.next() | |
| self.hand.append(self.deck[i]) | |
| self.counts[self.hand[-1]] += 1 | |
| self.seq.append(self.hand[-1]) | |
| del self.deck[i] | |
| if len(self.deck)==0: | |
| last = self.seq[-1] | |
| self.restart(announce = True) | |
| return last | |
| self.ri.seti(self.ri.i-1) | |
| return self.seq[-1] | |
| def leadPool(self): | |
| m = max(self.counts.values()) | |
| return [x for x in self.counts.keys() if self.counts[x] == m] | |
| def tailPool(self): | |
| m = min(self.counts.values()) | |
| return [x for x in self.counts.keys() if self.counts[x] == m] | |
| def restart(self,announce = False): | |
| print("\n"+" ".join(self.seq),self.deck,end=" -- refill\n\n") | |
| self.deck = self.deck+self.hand | |
| self.ri.seti(len(self.deck)) | |
| self.hand = [] | |
| self.seq = [] | |
| if announce: | |
| self.printSeq() | |
| #print(f"Lead: {' '.join(self.leadPool())}") | |
| print("\n". join([f"{str(x).center(len(str(max(self.counts.values()))))} : {' '.join([k for k,v in self.counts.items() if v == x])}" for x in range(max(self.counts.values()),min(self.counts.values())-1,-1) if x in self.counts.values()])+"\n") | |
| #print(f"Tail: {' '.join(self.tailPool())}") | |
| b = bingo(balls = ["-".join([str(__) for __ in _]) for _ in product([_ for _ in "BINGO"],[chr(_) for _ in range(48,55)])] ) | |
| while True: | |
| for _ in range(5): | |
| s = [] | |
| for __ in range(5): | |
| s.append(b.next()) | |
| print(" ".join(s)) | |
| time.sleep(1) | |
| b.restart() | |
| time.sleep(2) | |
| #print("-".join(["".join(b.next()) for _ in range(3)])) | |
| """ | |
| rx = randomIndexer() | |
| buckets = {} | |
| c = 0 | |
| while c<1000000: | |
| x = rx.next() | |
| try: | |
| buckets[x]+=1 | |
| except KeyError: | |
| buckets[x] = 1 | |
| c+=1 | |
| print(min(buckets.values()),max(buckets.values())) | |
| """ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment