This commit is contained in:
nannal
2020-01-26 21:03:32 +02:00
commit 562b320154
700 changed files with 120537 additions and 0 deletions

117
node_modules/deck/README.markdown generated vendored Normal file
View File

@@ -0,0 +1,117 @@
deck
====
Uniform and weighted shuffling and sampling for node.
examples
========
uniform shuffle
---------------
shuffle.js:
var deck = require('deck');
var xs = deck.shuffle([ 1, 2, 3, 4 ]);
console.log(xs);
output:
$ node shuffle.js
[ 1, 4, 2, 3 ]
uniform sample
--------------
pick.js:
var deck = require('deck');
var x = deck.pick([ 1, 2, 3, 4 ]);
console.log(x);
output:
$ node pick.js
2
weighted shuffle
----------------
wshuffle.js:
var deck = require('deck');
var xs = deck.shuffle({
a : 10,
b : 8,
c : 2,
d : 1,
e : 1,
});
console.log(xs);
output:
$ node wshuffle.js
[ 'b', 'a', 'c', 'd', 'e' ]
weighted sample
---------------
wpick.js:
var deck = require('deck');
var x = deck.pick({
a : 10,
b : 8,
c : 2,
d : 1,
e : 1,
});
console.log(x);
output:
$ node wpick.js
a
methods
=======
Note: both `deck(xs).pick()` and `deck.pick(xs)` styles work.
deck.shuffle(xs)
----------------
Return a new shuffled `xs` without mutating the original.
If `xs` is an Array, return a new shuffled Array based on a unifrom
distribution.
Otherwise if `xs` is an object, return a new shuffled Array of `xs`'s visible
keys based on the value weights of `xs`.
deck.pick(xs)
-------------
Sample `xs` without mutating `xs`.
If `xs` is an Array, return a random element from `xs` with a uniform
distribution.
Otherwise if `xs` is an object, return a random key from `xs` biased by its
normalized value.
deck.normalize(xs)
------------------
Return a new `xs` object where the values have been divided by the sum of all
the values such that the sum of all the values in the return object is 1.
If any weights are `< 0` normalize throws an error.
installation
============
With [npm](http://npmjs.org):
npm install deck

10
node_modules/deck/bench/shuffle.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
var shuffle = require('../').shuffle;
var xs = [];
for (var i = 0; i < 1e5; i++) {
xs.push(Math.floor(Math.random() * 1e3));
}
var t0 = Date.now();
shuffle(xs);
var elapsed = Date.now() - t0;
console.log(elapsed);

3
node_modules/deck/example/pick.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
var deck = require('deck');
var x = deck.pick([ 1, 2, 3, 4 ]);
console.log(x);

3
node_modules/deck/example/shuffle.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
var deck = require('deck');
var xs = deck.shuffle([ 1, 2, 3, 4 ]);
console.log(xs);

9
node_modules/deck/example/wpick.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
var deck = require('deck');
var x = deck.pick({
a : 10,
b : 8,
c : 2,
d : 1,
e : 1,
});
console.log(x);

9
node_modules/deck/example/wshuffle.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
var deck = require('deck');
var xs = deck.shuffle({
a : 10,
b : 8,
c : 2,
d : 1,
e : 1,
});
console.log(xs);

99
node_modules/deck/index.js generated vendored Normal file
View File

@@ -0,0 +1,99 @@
var exports = module.exports = function (xs) {
if (typeof xs !== 'object') { // of which Arrays are
throw new TypeError('Must be an Array or an object');
}
return Object.keys(exports).reduce(function (acc, name) {
acc[name] = exports[name].bind(null, xs);
return acc;
}, {});
};
exports.shuffle = function (xs) {
if (Array.isArray(xs)) {
// uniform shuffle
var res = xs.slice();
for (var i = res.length - 1; i >= 0; i--) {
var n = Math.floor(Math.random() * i);
var t = res[i];
res[i] = res[n];
res[n] = t;
}
return res;
}
else if (typeof xs === 'object') {
// weighted shuffle
var weights = Object.keys(xs).reduce(function (acc, key) {
acc[key] = xs[key];
return acc;
}, {});
var ret = [];
while (Object.keys(weights).length > 0) {
var key = exports.pick(weights);
delete weights[key];
ret.push(key);
}
return ret;
}
else {
throw new TypeError('Must be an Array or an object');
}
};
exports.pick = function (xs) {
if (Array.isArray(xs)) {
// uniform sample
return xs[Math.floor(Math.random() * xs.length)];
}
else if (typeof xs === 'object') {
// weighted sample
var weights = exports.normalize(xs);
if (!weights) return undefined;
var n = Math.random();
var threshold = 0;
var keys = Object.keys(weights);
for (var i = 0; i < keys.length; i++) {
threshold += weights[keys[i]];
if (n < threshold) return keys[i];
}
throw new Error('Exceeded threshold. Something is very wrong.');
}
else {
throw new TypeError('Must be an Array or an object');
}
};
exports.normalize = function (weights) {
if (typeof weights !== 'object' || Array.isArray(weights)) {
throw 'Not an object'
}
var keys = Object.keys(weights);
if (keys.length === 0) return undefined;
var total = keys.reduce(function (sum, key) {
var x = weights[key];
if (x < 0) {
throw new Error('Negative weight encountered at key ' + key);
}
else if (typeof x !== 'number') {
throw new TypeError('Number expected, got ' + typeof x);
}
else {
return sum + x;
}
}, 0);
return total === 1
? weights
: keys.reduce(function (acc, key) {
acc[key] = weights[key] / total;
return acc;
}, {})
;
};

67
node_modules/deck/package.json generated vendored Normal file
View File

@@ -0,0 +1,67 @@
{
"_from": "deck@>=0.0.3",
"_id": "deck@0.0.4",
"_inBundle": false,
"_integrity": "sha1-1NidRguoHuggsEoFp9Dc5k2Lcwo=",
"_location": "/deck",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "deck@>=0.0.3",
"name": "deck",
"escapedName": "deck",
"rawSpec": ">=0.0.3",
"saveSpec": null,
"fetchSpec": ">=0.0.3"
},
"_requiredBy": [
"/markov"
],
"_resolved": "https://registry.npmjs.org/deck/-/deck-0.0.4.tgz",
"_shasum": "d4d89d460ba81ee820b04a05a7d0dce64d8b730a",
"_spec": "deck@>=0.0.3",
"_where": "/home/dabbott/dev/chainy/node_modules/markov",
"author": {
"name": "James Halliday",
"email": "mail@substack.net",
"url": "http://substack.net"
},
"bugs": {
"url": "https://github.com/substack/node-deck/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Uniform and weighted shuffling and sampling",
"devDependencies": {
"expresso": ">=0.7.0"
},
"directories": {
"lib": ".",
"example": "./example"
},
"engines": {
"node": ">=0.4.0"
},
"homepage": "https://github.com/substack/node-deck#readme",
"keywords": [
"shuffle",
"sample",
"normalize",
"pick",
"choose",
"cards",
"weights"
],
"license": "MIT/X11",
"main": "./index.js",
"name": "deck",
"repository": {
"type": "git",
"url": "git://github.com/substack/node-deck.git"
},
"scripts": {
"test": "expresso"
},
"version": "0.0.4"
}

20
node_modules/deck/test/normalize.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
var deck = require('deck');
var assert = require('assert');
var eql = assert.deepEqual;
exports.normalize = function () {
eql(
deck.normalize({ a : 1, b : 3, c : 4 }),
{ a : 0.125, b : 0.375, c : 0.5 }
);
var t = 0.1 + 0.2 + 0.05;
eql(
deck.normalize({ a : 0.1, b : 0.2, c : 0.05 }),
{ a : 0.1 / t, b : 0.2 / t, c : 0.05 / t }
);
assert.throws(function () {
deck.normalize({ a : 0.1, b : 0.2, c : [] });
});
};

69
node_modules/deck/test/pick.js generated vendored Normal file
View File

@@ -0,0 +1,69 @@
var deck = require('deck');
var assert = require('assert');
var eql = assert.deepEqual;
function picker (fn) {
var xs = [0,1,2,3,4,5,6,7,8,9];
var counts = {};
var loops = 50000;
for (var i = 0; i < loops; i++) {
var x = fn(xs);
counts[x] = (counts[x] || 0) + 1;
}
eql(Object.keys(counts).sort(), xs);
eql(xs, [0,1,2,3,4,5,6,7,8,9], 'shuffle mutated its argument');
xs.forEach(function (x) {
assert.ok(
counts[x] * xs.length >= loops * 0.95
);
assert.ok(
counts[x] * xs.length <= loops * 1.05
);
});
}
exports.pick = function () {
picker(deck.pick);
};
exports.pickObj = function () {
picker(function (xs) {
return deck(xs).pick()
});
};
exports.weightedPick = function () {
var counts = {};
var weights = { a : 2, b : 10, c : 1 };
var total = 2 + 10 + 1;
var loops = 50000;
for (var i = 0; i < loops; i++) {
var x = deck.pick(weights);
counts[x] = (counts[x] || 0) + 1;
}
eql(Object.keys(counts).sort(), [ 'a', 'b', 'c' ]);
Object.keys(weights).forEach(function (key) {
assert.ok(
counts[key] / weights[key] * total >= loops * 0.95
);
assert.ok(
counts[key] / weights[key] * total <= loops * 1.05
);
});
assert.throws(function () {
deck.pick({ a : 5, b : 2, c : /moo/ });
});
};
exports.pickEmpty = function () {
assert.ok(deck.pick([]) === undefined);
assert.ok(deck.pick({}) === undefined);
};

71
node_modules/deck/test/shuffle.js generated vendored Normal file
View File

@@ -0,0 +1,71 @@
var deck = require('deck');
var assert = require('assert');
function shuffler (fn) {
var xs = [0,1,2,3,4,5,6,7,8,9];
var xs_ = fn(xs);
assert.eql(xs, [0,1,2,3,4,5,6,7,8,9], 'shuffle mutated its argument');
assert.eql(xs.length, 10);
assert.ok(xs.every(function (x) {
return xs_.indexOf(x) >= 0
}));
}
exports.shuffle = function () {
shuffler(deck.shuffle);
};
exports.quick = function () {
var xs = [];
for (var i = 0; i < 1e5; i++) xs.push(Math.random());
var t0 = Date.now();
var xs_ = deck.shuffle(xs);
var elapsed = Date.now() - t0;
assert.ok(elapsed < 200);
assert.equal(xs.length, 1e5);
};
exports.shuffleObj = function () {
shuffler(function (xs) {
return deck(xs).shuffle()
});
};
exports.weightedShuffle = function () {
assert.eql(deck.shuffle({ a : 1000, b : 0.01 }), [ 'a', 'b' ]);
var weights = { a : 3, b : 1, c : 10 };
var total = 3 + 1 + 10;
var loops = 5000;
var counts = {};
for (var i = 0; i < loops; i++) {
var x = deck.shuffle(weights).join('');
counts[x] = (counts[x] || 0) + 1;
}
function margins (key) {
var keys = key.split('');
var expected = key.split('').reduce(function (p, x) {
var p_ = p * weights[x] / keys.reduce(function (acc, k) {
return acc + weights[k];
}, 0);
keys.shift();
return p_;
}, loops);
assert.ok(counts[key] >= 0.95 * expected);
assert.ok(counts[key] <= 1.05 * expected);
}
Object.keys(counts).every(margins);
assert.throws(function () {
deck.shuffle({ a : 1, b : 'x', c : 5 });
});
};
exports.shuffleEmpty = function () {
assert.eql(deck.shuffle([]), []);
assert.eql(deck.shuffle({}), []);
};