#!/usr/bin/ruby
#
## https://rosettacode.org/wiki/Subtractive_generator
#
class SubRandom(seed, state=[]) {
const mod = 1_000_000_000;
method init {
var s = [seed % mod, 1];
53.times {
s.append((s[-2] - s[-1]) % mod);
}
state = s.range.map {|i| s[(34 + 34*i) % 55] };
range(55, 219).each { self.subrand };
}
method subrand {
var x = ((state.shift - state[-24]) % mod);
state.append(x);
return x;
}
}
## Tests
var r1 = SubRandom(292929);
assert_eq(r1.subrand, 467478574);
var r2 = SubRandom(123456);
assert_eq(r2.subrand, 53516807);
assert_eq(r2.subrand, 810719496);
assert_eq(r1.subrand, 512932792);
assert_eq(r1.subrand, 539453717);
assert_eq(r2.subrand, 781070541);
say "** Test passed!";