Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 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)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement