Skip to content

Instantly share code, notes, and snippets.

@briancavalier
Last active February 20, 2016 02:32
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 briancavalier/f71314fcff5e7870608e to your computer and use it in GitHub Desktop.
Save briancavalier/f71314fcff5e7870608e to your computer and use it in GitHub Desktop.
Pure, splittable version of BurtlePRNG
// BurtlePRNG ported from https://github.com/graue/burtleprng
// Immutable + splittable + ES2015 by @briancavalier
// newRandom :: UInt32 -> UInt32 -> UInt32 -> UInt32 -> Gen a
// Create a new prng with exact state
export const newRandom = (s0, s1, s2, s3) =>
new BurtlePRNG(s0>>>0, s1>>>0, s2>>>0, s3>>>0);
// seedRandom :: UInt32 -> Gen a
// Create a new prng from a 32-bit int seed
export const seedRandom = seed => {
const s123 = seed >>> 0;
return prime(20, new BurtlePRNG(S0, s123, s123, s123));
}
// splitn :: Int -> Gen a -> [Gen a]
// Create n new distinct, but deterministic prngs based on g
// Ugly imperative impl for speed
export const splitn = (n, g) => {
const a = new Array(n);
for(let i = 0; i < n; ++i) {
const { value, next } = g.next();
a[i] = next;
g = seedRandom(value);
}
return a;
}
// prime :: Int -> Gen a -> Gen a
// Consume n randoms to "prime" prng
// Ugly imperative impl for speed
const prime = (n, g) => {
for (let i = 0; i < n; ++i) {
const { value, next } = g.next();
g = next;
}
return g;
};
const rot = (x, k) => (x << k) | (x >> (32-k));
const S0 = 0xf1ea5eed;
const REAL_DIVISOR = 4294967296.0;
class BurtlePRNG {
constructor(s0, s1, s2, s3) {
this.s0 = s0;
this.s1 = s1;
this.s2 = s2;
this.s3 = s3;
}
next() {
const e = (this.s0 - rot(this.s1, 27))>>>0;
const s0 = (this.s1 ^ rot(this.s2, 17))>>>0;
const s1 = (this.s2 + this.s3)>>>0;
const s2 = (this.s3 + e)>>>0;
const s3 = (e + s0)>>>0;
return { value: s3, next: new BurtlePRNG(s0, s1, s2, s3) };
}
nextReal() {
const { value, next } = this.next();
return { value: value/REAL_DIVISOR, next };
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment