Skip to content

Instantly share code, notes, and snippets.

@need12648430
Last active August 29, 2015 14:20
Show Gist options
  • Save need12648430/9b36ed78fe2bc8753afc to your computer and use it in GitHub Desktop.
Save need12648430/9b36ed78fe2bc8753afc to your computer and use it in GitHub Desktop.
Linear congruential generator (Seedable PRNG) with weighted choices and shuffling in 1.4kb of clean JS.
var LCG = (function () {
var c = 0x93456789, a = 0x169659, mod, mask, r;
mask = (mod = Math.pow(2, 31)) - 1;
function LCG(seed) {
this.seed = seed || new Date().getTime();
}
LCG.prototype = {
nextInt:
function () {
r = this.seed + c;
this.seed = (this.seed * a + c) & mask;
r = ((r ^ (r >>> 16)) * a) & mask;
return r ^ (r >>> 16);
},
nextFloat:
function () {return this.nextInt() / mod},
rangeInt:
function (start, end) {
var n;
while ((n = this.nextInt()) > mod - mod % (end - start)) ;
return start + n % (end - start);
},
rangeFloat:
function (start, end) {return start + this.nextFloat() * (end - start);},
choose:
function (set, weights) {
if (!weights) return set[LCG.prototype.rangeInt(0, set.length)];
if (set.length != weights.length) throw "Set length must match weights length.";
var i, t, s, a;
for (t = i = 0; i < set.length; t += weights[i ++]);
s = this.rangeFloat(0, t);
for (i = a = 0; a < t; a += weights.shift(i ++))
if (s >= a && s < a + weights[0])
return set[i];
},
shuffle:
function (set) {
for (
var copy = set.slice(0), out = [];
copy.length > 0;
out.push(copy.splice(this.nextInt() % copy.length, 1)[0])
);
return out;
}
};
return LCG;
})();
@sbrl
Copy link

sbrl commented May 25, 2015

This looks really cool. Definitely going to star this for use in a future project.

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