Skip to content

Instantly share code, notes, and snippets.

@vorushin
Created July 4, 2012 10:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vorushin/3046736 to your computer and use it in GitHub Desktop.
Save vorushin/3046736 to your computer and use it in GitHub Desktop.
My python implementation of pseudo-rng algorithm from http://amca01.wordpress.com/2012/07/02/a-conceptually-simple-prng/
def prng(n):
p = (1 << 31) - 1
arr = [0 for i in range(n + 1)]
arr[0] = 7
arr[1] = 7
for i in range(2, n + 1):
arr[i] = pow_mod(7, arr[i - 1], p) + pow_mod(7, arr[i - 2], p)
return arr
def pow_mod(base, power, p):
if power == 0:
return 1
result = base
for k in range(2, power + 1):
result *= base # result == base ** k
if result >= p:
c = result % p
# d - how many times we multiple (base ** k) * (base ** k) * ...
# e - the rest of power
d, e = divmod(power, k)
# now pow_mod(base, power, p) ==
# pow_mod(c, d, p) -- fast calculation using mod properties
# * pow_mod(base, e, p) -- the rest
#
# mod properties explained:
# (base ** k) * (base ** k) * ... [d times] ... * (base ** k) mod p
# == ((base ** k) mod p) ** d
return (pow_mod(c, d, p) * pow_mod(base, e, p)) % p
else:
return result
def test_pow_mod():
assert pow_mod(7, 100, 9999) == 7 ** 100 % 9999
test_pow_mod()
from pprint import pprint
pprint(prng(50))
@vorushin
Copy link
Author

vorushin commented Jul 4, 2012

It generates 1 million numbers in 13 seconds when launched under pypy 1.9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment