require "set"
N=32
srand ARGV[0]&.to_i
class P < Array
def self.rand
new(N.times.to_a.shuffle)
end
def *(o)
case o
when Array
P.new(self.map{|a| o[a]})
when Integer
o_bin = "%0#{N}b" % o
(self * o_bin.chars).join.to_i(2)
end
end
def !
@inv ||= P.new(self.map.with_index.sort_by{|i,v| i}.map{|i,v| v})
end
end
def bytes(r)
(N/8).times.map do
r,a = [r>>8, r & 0xff]
a.chr
end
end
def prng
x = P.rand
y = P.rand
r = rand(2**N)
Enumerator.new do |out|
loop do
out << r ^= y * r
y = x*y*!x
end
end
end
s=Set.new
open("rand.dat", "wb") do |f|
prng.lazy.take(100).each do |r|
if s && !s.add?(r)
puts s.length
s = nil
end
f.write bytes(r)
end
end