Skip to content

Instantly share code, notes, and snippets.

@chemacortes
Created July 6, 2019 15:30
Show Gist options
  • Save chemacortes/3d66daf14b2ebd2190cd50d969defaed to your computer and use it in GitHub Desktop.
Save chemacortes/3d66daf14b2ebd2190cd50d969defaed to your computer and use it in GitHub Desktop.
Generate randint(1,7) using randint(1,5) as the only random function
from random import randint
from functools import partial
from collections import Counter
from itertools import cycle
from typing import Iterable
# única función random que se permite usar
rand5 = partial(randint, 1, 5)
# yapf: disable
# matriz de conversión
conv = [
[1, 2, 3, 4, 5],
[6, 7, 1, 2, 3],
[4, 5, 6, 7, 1],
[2, 3, 4, 5, 6],
[7, 0, 0, 0, 0]
]
# yapf: enable
def rand7() -> int:
"""
Generador aleatorio de números en rango [1,7]
a partir de randint(1,5)
"""
res = 0
while not res:
# tomamos dos números aleatorios en el rango [1,5]
(a, b) = (rand5(), rand5())
# buscamos su correspondencia en el rango [1,7]
res = conv[a - 1][b - 1]
return res
def rand7_gen() -> Iterable[int]:
"""
Generador aleatorio de números en rango [1,7]
a partir de randint(1,5). Versión optimizada.
"""
cycle7 = cycle((i, j) for i in range(1, 8) for j in range(1, 8))
conv = [[[next(cycle7) for i in range(5)] for j in range(5)]
for k in range(5)]
while True:
# tomamos tres números aleatorios en el rango [0,4]
(a, b, c) = (rand5() - 1, rand5() - 1, rand5() - 1)
num = a * 5**2 + b * 5 + c
if num < 2 * 7**2:
(r, s) = conv[a][b][c]
yield r
yield s
def test_rand(r, *, N=70000):
media = N / 7
frecuencias = Counter(r() for _ in range(N))
print(frecuencias)
print(", ".join(f"{(v - media) / media :.2%}"
for v in frecuencias.values()))
if __name__ == "__main__":
print("Randin(1,7) nativo")
test_rand(partial(randint, 1, 7))
print("Randin(1,7) generado")
test_rand(rand7)
print("Randin(1,7) generado2")
r = rand7_gen()
test_rand(partial(next, r))
print("Randin(1,7) generado2")
r = rand7_gen()
test_rand(partial(next, r), N=140000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment