Skip to content

Commit

Permalink
Starting random inplementation
Browse files Browse the repository at this point in the history
  • Loading branch information
CrossEye committed Jul 16, 2014
1 parent 977e522 commit 5600525
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 0 deletions.
120 changes: 120 additions & 0 deletions ext/random/random.js
@@ -0,0 +1,120 @@
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['ramda'], factory);
} else if (typeof exports === 'object') {
module.exports = factory(require('../../ramda'));
} else {
root.Random = factory(root.ramda);
}
}(this, function (R) {

// Random
// ----------
//
// TODO: (possibly?)
// var random = new Random(seeds); // then...
// random.nextInt(below): () -> random int, where 0 <= int < < below
// random.intBetween(start, upTo): () -> random int, where start <= int < upTo
// random.boolean(): () -> random boolean
// random.fromChars(characters): int -> random String consisting of `int` chars drawn from `characters`.

// From http://baagoe.com/en/RandomMusings/javascript/
// mirrored at https://github.com/nquinlan/better-random-numbers-for-javascript-mirror
// Johannes Baagøe <baagoe@baagoe.com>, 2010
var Mash = function Mash() {
var n = 0xefc8249d;

var mash = function (data) {
data = data.toString();
for (var i = 0; i < data.length; i++) {
n += data.charCodeAt(i);
var h = 0.02519603282416938 * n;
n = h >>> 0;
h -= n;
h *= n;
n = h >>> 0;
h -= n;
n += h * 0x100000000; // 2^32
}
return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
};

mash.version = 'Mash 0.9';
return mash;
};

// From http://baagoe.com/en/RandomMusings/javascript/
// mirrored at https://github.com/nquinlan/better-random-numbers-for-javascript-mirror
// Johannes Baagøe <baagoe@baagoe.com>, 2010
var Random = function Random() {
return (function (args) {
var s0 = 0;
var s1 = 0;
var s2 = 0;
var c = 1;

if (args.length == 0) {
args = [+new Date];
}
var mash = Mash();
s0 = mash(' ');
s1 = mash(' ');
s2 = mash(' ');

for (var i = 0; i < args.length; i++) {
s0 -= mash(args[i]);
if (s0 < 0) {
s0 += 1;
}
s1 -= mash(args[i]);
if (s1 < 0) {
s1 += 1;
}
s2 -= mash(args[i]);
if (s2 < 0) {
s2 += 1;
}
}
mash = null;

var random = function () {
var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32
s0 = s1;
s1 = s2;
return s2 = t - (c = t | 0);
};
random.uint32 = function () {
return random() * 0x100000000; // 2^32
};
random.fract53 = function () {
return random() +
(random() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53
};
random.version = 'Alea 0.9';
random.args = args;
return random;

}(Array.prototype.slice.call(arguments)));
};

// Returns a shuffled version of a list, using the
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
var shuffle = R.shuffle = function(random, list) {
var idx = -1;
var len = list.length;
var position;
var result = [];
while (++idx < len) {
position = Math.floor((idx + 1) * random());
result[idx] = result[position];
result[position] = list[idx];
}
return result;
};

R.Random = Random;

return Random;
}));


42 changes: 42 additions & 0 deletions ext/random/test/test.random.js
@@ -0,0 +1,42 @@
var assert = require('assert');
var Lib = require('../../../ramda');
var Random = require('../random');

describe('Random', function() {
it('is a function', function() {
assert.equal(typeof Random, 'function');
});

it('returns a function', function() {
assert.equal(typeof Random(), 'function');
});

it('returns consistent results for the same seeds', function() {
var random = new Random("my", 3, "seeds");
assert.equal(random(), 0.30802189325913787);
assert.equal(random(), 0.5190450621303171);
assert.equal(random(), 0.43635262292809784);
});

it('but returns entirely different results for even slightly different seeds', function() {
var random = new Random("my", 3, "weeds");
assert.equal(random(), 0.7021001486573368);
assert.equal(random(), 0.6134823360480368);
assert.equal(random(), 0.6507473199162632);
});
});

describe('shuffle', function() {
var shuffle = Lib.shuffle;
var random;

beforeEach(function() {
random = Random("my", 3, "seeds");
});

it('returns a shuffled copy of a list', function() {
var list = [1, 2, 3,4, 5, 6, 7, 8, 9, 10];
assert.deepEqual(shuffle(random, list), [6, 3, 4, 8, 5, 1, 7, 10, 2, 9]);
});

});

0 comments on commit 5600525

Please sign in to comment.