Created
July 6, 2019 15:30
-
-
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
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 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