├── README.md ├── lib └── generator.js ├── node_modules └── mersenne-twister │ ├── .npmignore │ ├── .travis.yml │ ├── Makefile │ ├── README.md │ ├── package.json │ ├── src │ └── mersenne-twister.js │ └── test │ └── generator.js ├── package-lock.json └── package.json /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Description 4 | 5 | Generates an array of unique random integers using a Mersenne-twister algorithm. 6 | 7 | ## Install 8 | 9 | ```bash 10 | npm install random-array-generator 11 | ``` 12 | 13 | ## Usage 14 | 15 | Add the following line of code to your project: 16 | 17 | ```bash 18 | var generator = require('random-array-generator'); 19 | ``` 20 | 21 | To generate an array of random numbers, pass an object into the "randomArray()" function, which will then return an array containing the generated numbers. The object __*must*__ be in the form: 22 | 23 | ```bash 24 | generator.randomArray({min: x, max: y, elements: z}); 25 | ``` 26 | 27 | Where __*x*__ and __*y*__ represents the range (inclusive) of the random numbers to be generated and __*z*__ is the number of random integers to be generated. 28 | 29 | __*Example:*__ 30 | ```bash 31 | // import package into your project 32 | var generator = require('random-array-generator'); 33 | 34 | // Generate 6 random numbers between 1 and 49 (inclusive) and log to the console. 35 | console.log(generator.randomArray({min: 1, max: 49, elements: 6})); 36 | 37 | // Result: [2, 34, 17, 11, 47, 25] 38 | ``` 39 | 40 | ## Acknowledgments 41 | 42 | [mersenne-twister](https://www.npmjs.com/package/mersenne-twister) 43 | 44 | ## License 45 | 46 | [MIT](http://vjpr.mit-license.org) 47 | -------------------------------------------------------------------------------- /lib/generator.js: -------------------------------------------------------------------------------- 1 | var MersenneTwister = require('mersenne-twister'); 2 | var generator = new MersenneTwister(); 3 | 4 | 5 | function containsVal(arr, val){ 6 | for(var i = 0; i < arr.length; i++){ 7 | if(arr[i] == val){ 8 | return true; 9 | } 10 | } 11 | return false; 12 | } 13 | 14 | 15 | //{max: x, min: y; elements: z} 16 | exports.randomArray = function(arg) { 17 | var tempArr = []; 18 | var tempNum; 19 | 20 | for(var i = 0; i < arg.elements; i++){ 21 | 22 | do{ 23 | tempNum = Math.ceil((generator.random()*(arg.max - arg.min)) + arg.min); 24 | } 25 | while (containsVal(tempArr, tempNum)); 26 | 27 | tempArr.push(tempNum); 28 | } 29 | 30 | return tempArr; 31 | } 32 | -------------------------------------------------------------------------------- /node_modules/mersenne-twister/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | -------------------------------------------------------------------------------- /node_modules/mersenne-twister/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.8" 4 | -------------------------------------------------------------------------------- /node_modules/mersenne-twister/Makefile: -------------------------------------------------------------------------------- 1 | test: 2 | ./node_modules/mocha/bin/_mocha -R spec -r should test --recursive 3 | 4 | .PHONY: test 5 | -------------------------------------------------------------------------------- /node_modules/mersenne-twister/README.md: -------------------------------------------------------------------------------- 1 | ## Pseudorandom number generator [![Build Status](https://travis-ci.org/boo1ean/mersenne-twister.png?branch=master)](https://travis-ci.org/boo1ean/mersenne-twister) 2 | 3 | Mersenne Twister pseudorandom number generator. 4 | 5 | [Origin source](https://gist.github.com/banksean/300494) (generator interface was changed) 6 | 7 | Algorithm - http://en.wikipedia.org/wiki/Mersenne_twister 8 | 9 | ## Installation 10 | 11 | $ npm install mersenne-twister 12 | 13 | ## Usage 14 | 15 | ```javascript 16 | var MersenneTwister = require('mersenne-twister'); 17 | var generator = new MersenneTwister(); 18 | 19 | // Generates a random number on [0,1) real interval (same interval as Math.random) 20 | generator.random(); 21 | 22 | // [0, 4294967295] 23 | generator.random_int(); 24 | 25 | // [0,1] 26 | generator.random_incl(); 27 | 28 | // (0,1) 29 | generator.random_excl(); 30 | 31 | // [0,1) with 53-bit resolution 32 | generator.random_long(); 33 | 34 | // [0, 2147483647] 35 | generator.random_int31(); 36 | ``` 37 | 38 | ## Seeding 39 | 40 | If you want to use a specific seed in order to get a repeatable random sequence, pass an integer into the constructor: 41 | 42 | ```javascript 43 | var generator = new MersenneTwister(123); 44 | ``` 45 | 46 | and that will always produce the same random sequence. 47 | 48 | Also you can do it on existing generator instance: 49 | 50 | ```javascript 51 | generator.init_seed(123); 52 | ``` 53 | 54 | ## License 55 | 56 | See source 57 | -------------------------------------------------------------------------------- /node_modules/mersenne-twister/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "mersenne-twister@latest", 3 | "_id": "mersenne-twister@1.1.0", 4 | "_inBundle": false, 5 | "_integrity": "sha1-+RZhjuQ9cXnvz2Qb7EUx65Zwl4o=", 6 | "_location": "/mersenne-twister", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "tag", 10 | "registry": true, 11 | "raw": "mersenne-twister@latest", 12 | "name": "mersenne-twister", 13 | "escapedName": "mersenne-twister", 14 | "rawSpec": "latest", 15 | "saveSpec": null, 16 | "fetchSpec": "latest" 17 | }, 18 | "_requiredBy": [ 19 | "/" 20 | ], 21 | "_resolved": "https://registry.npmjs.org/mersenne-twister/-/mersenne-twister-1.1.0.tgz", 22 | "_shasum": "f916618ee43d7179efcf641bec4531eb9670978a", 23 | "_spec": "mersenne-twister@latest", 24 | "_where": "/home/willie/Projects/WebDev/git/npm/random-array-generator", 25 | "author": { 26 | "name": "Egor Gumenyuk", 27 | "email": "boo1ean0807@gmail.com" 28 | }, 29 | "bugs": { 30 | "url": "https://github.com/boo1ean/mersenne-twister/issues" 31 | }, 32 | "bundleDependencies": false, 33 | "deprecated": false, 34 | "description": "Mersenne twister pseudorandom number generator", 35 | "devDependencies": { 36 | "mocha": "~1.17.1", 37 | "should": "~3.1.2" 38 | }, 39 | "homepage": "https://github.com/boo1ean/mersenne-twister", 40 | "keywords": [ 41 | "random", 42 | "mersenne", 43 | "twister", 44 | "mersennetwister", 45 | "generator", 46 | "seed" 47 | ], 48 | "license": "MIT", 49 | "main": "src/mersenne-twister.js", 50 | "name": "mersenne-twister", 51 | "repository": { 52 | "type": "git", 53 | "url": "git://github.com/boo1ean/mersenne-twister.git" 54 | }, 55 | "scripts": { 56 | "test": "make test" 57 | }, 58 | "version": "1.1.0" 59 | } 60 | -------------------------------------------------------------------------------- /node_modules/mersenne-twister/src/mersenne-twister.js: -------------------------------------------------------------------------------- 1 | /* 2 | https://github.com/banksean wrapped Makoto Matsumoto and Takuji Nishimura's code in a namespace 3 | so it's better encapsulated. Now you can have multiple random number generators 4 | and they won't stomp all over eachother's state. 5 | 6 | If you want to use this as a substitute for Math.random(), use the random() 7 | method like so: 8 | 9 | var m = new MersenneTwister(); 10 | var randomNumber = m.random(); 11 | 12 | You can also call the other genrand_{foo}() methods on the instance. 13 | 14 | If you want to use a specific seed in order to get a repeatable random 15 | sequence, pass an integer into the constructor: 16 | 17 | var m = new MersenneTwister(123); 18 | 19 | and that will always produce the same random sequence. 20 | 21 | Sean McCullough (banksean@gmail.com) 22 | */ 23 | 24 | /* 25 | A C-program for MT19937, with initialization improved 2002/1/26. 26 | Coded by Takuji Nishimura and Makoto Matsumoto. 27 | 28 | Before using, initialize the state by using init_seed(seed) 29 | or init_by_array(init_key, key_length). 30 | 31 | Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, 32 | All rights reserved. 33 | 34 | Redistribution and use in source and binary forms, with or without 35 | modification, are permitted provided that the following conditions 36 | are met: 37 | 38 | 1. Redistributions of source code must retain the above copyright 39 | notice, this list of conditions and the following disclaimer. 40 | 41 | 2. Redistributions in binary form must reproduce the above copyright 42 | notice, this list of conditions and the following disclaimer in the 43 | documentation and/or other materials provided with the distribution. 44 | 45 | 3. The names of its contributors may not be used to endorse or promote 46 | products derived from this software without specific prior written 47 | permission. 48 | 49 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 50 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 51 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 52 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 53 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 54 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 55 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 56 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 57 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 58 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 59 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 60 | 61 | 62 | Any feedback is very welcome. 63 | http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html 64 | email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) 65 | */ 66 | 67 | var MersenneTwister = function(seed) { 68 | if (seed == undefined) { 69 | seed = new Date().getTime(); 70 | } 71 | 72 | /* Period parameters */ 73 | this.N = 624; 74 | this.M = 397; 75 | this.MATRIX_A = 0x9908b0df; /* constant vector a */ 76 | this.UPPER_MASK = 0x80000000; /* most significant w-r bits */ 77 | this.LOWER_MASK = 0x7fffffff; /* least significant r bits */ 78 | 79 | this.mt = new Array(this.N); /* the array for the state vector */ 80 | this.mti=this.N+1; /* mti==N+1 means mt[N] is not initialized */ 81 | 82 | if (seed.constructor == Array) { 83 | this.init_by_array(seed, seed.length); 84 | } 85 | else { 86 | this.init_seed(seed); 87 | } 88 | } 89 | 90 | /* initializes mt[N] with a seed */ 91 | /* origin name init_genrand */ 92 | MersenneTwister.prototype.init_seed = function(s) { 93 | this.mt[0] = s >>> 0; 94 | for (this.mti=1; this.mti>> 30); 96 | this.mt[this.mti] = (((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253) 97 | + this.mti; 98 | /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ 99 | /* In the previous versions, MSBs of the seed affect */ 100 | /* only MSBs of the array mt[]. */ 101 | /* 2002/01/09 modified by Makoto Matsumoto */ 102 | this.mt[this.mti] >>>= 0; 103 | /* for >32 bit machines */ 104 | } 105 | } 106 | 107 | /* initialize by an array with array-length */ 108 | /* init_key is the array for initializing keys */ 109 | /* key_length is its length */ 110 | /* slight change for C++, 2004/2/26 */ 111 | MersenneTwister.prototype.init_by_array = function(init_key, key_length) { 112 | var i, j, k; 113 | this.init_seed(19650218); 114 | i=1; j=0; 115 | k = (this.N>key_length ? this.N : key_length); 116 | for (; k; k--) { 117 | var s = this.mt[i-1] ^ (this.mt[i-1] >>> 30) 118 | this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1664525) << 16) + ((s & 0x0000ffff) * 1664525))) 119 | + init_key[j] + j; /* non linear */ 120 | this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */ 121 | i++; j++; 122 | if (i>=this.N) { this.mt[0] = this.mt[this.N-1]; i=1; } 123 | if (j>=key_length) j=0; 124 | } 125 | for (k=this.N-1; k; k--) { 126 | var s = this.mt[i-1] ^ (this.mt[i-1] >>> 30); 127 | this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1566083941) << 16) + (s & 0x0000ffff) * 1566083941)) 128 | - i; /* non linear */ 129 | this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */ 130 | i++; 131 | if (i>=this.N) { this.mt[0] = this.mt[this.N-1]; i=1; } 132 | } 133 | 134 | this.mt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */ 135 | } 136 | 137 | /* generates a random number on [0,0xffffffff]-interval */ 138 | /* origin name genrand_int32 */ 139 | MersenneTwister.prototype.random_int = function() { 140 | var y; 141 | var mag01 = new Array(0x0, this.MATRIX_A); 142 | /* mag01[x] = x * MATRIX_A for x=0,1 */ 143 | 144 | if (this.mti >= this.N) { /* generate N words at one time */ 145 | var kk; 146 | 147 | if (this.mti == this.N+1) /* if init_seed() has not been called, */ 148 | this.init_seed(5489); /* a default initial seed is used */ 149 | 150 | for (kk=0;kk>> 1) ^ mag01[y & 0x1]; 153 | } 154 | for (;kk>> 1) ^ mag01[y & 0x1]; 157 | } 158 | y = (this.mt[this.N-1]&this.UPPER_MASK)|(this.mt[0]&this.LOWER_MASK); 159 | this.mt[this.N-1] = this.mt[this.M-1] ^ (y >>> 1) ^ mag01[y & 0x1]; 160 | 161 | this.mti = 0; 162 | } 163 | 164 | y = this.mt[this.mti++]; 165 | 166 | /* Tempering */ 167 | y ^= (y >>> 11); 168 | y ^= (y << 7) & 0x9d2c5680; 169 | y ^= (y << 15) & 0xefc60000; 170 | y ^= (y >>> 18); 171 | 172 | return y >>> 0; 173 | } 174 | 175 | /* generates a random number on [0,0x7fffffff]-interval */ 176 | /* origin name genrand_int31 */ 177 | MersenneTwister.prototype.random_int31 = function() { 178 | return (this.random_int()>>>1); 179 | } 180 | 181 | /* generates a random number on [0,1]-real-interval */ 182 | /* origin name genrand_real1 */ 183 | MersenneTwister.prototype.random_incl = function() { 184 | return this.random_int()*(1.0/4294967295.0); 185 | /* divided by 2^32-1 */ 186 | } 187 | 188 | /* generates a random number on [0,1)-real-interval */ 189 | MersenneTwister.prototype.random = function() { 190 | return this.random_int()*(1.0/4294967296.0); 191 | /* divided by 2^32 */ 192 | } 193 | 194 | /* generates a random number on (0,1)-real-interval */ 195 | /* origin name genrand_real3 */ 196 | MersenneTwister.prototype.random_excl = function() { 197 | return (this.random_int() + 0.5)*(1.0/4294967296.0); 198 | /* divided by 2^32 */ 199 | } 200 | 201 | /* generates a random number on [0,1) with 53-bit resolution*/ 202 | /* origin name genrand_res53 */ 203 | MersenneTwister.prototype.random_long = function() { 204 | var a=this.random_int()>>>5, b=this.random_int()>>>6; 205 | return(a*67108864.0+b)*(1.0/9007199254740992.0); 206 | } 207 | 208 | /* These real versions are due to Isaku Wada, 2002/01/09 added */ 209 | 210 | module.exports = MersenneTwister; 211 | -------------------------------------------------------------------------------- /node_modules/mersenne-twister/test/generator.js: -------------------------------------------------------------------------------- 1 | var MersenneTwister = require('../'); 2 | var g = new MersenneTwister(); 3 | 4 | describe('Generator', function() { 5 | it('Should repeat random sequence on same seed', function() { 6 | var seed = 123; 7 | 8 | g.init_seed(seed); 9 | var first_1 = g.random(); 10 | var first_2 = g.random(); 11 | 12 | g.init_seed(seed); 13 | var second_1 = g.random(); 14 | var second_2 = g.random(); 15 | 16 | first_1.should.be.exactly(second_1); 17 | first_2.should.be.exactly(second_2); 18 | }); 19 | 20 | it('Should allow seeding via constructor', function() { 21 | var seed = 325; 22 | var g1 = new MersenneTwister(seed); 23 | var g2 = new MersenneTwister(seed); 24 | 25 | for (var i = 0; i < 5; ++i) { 26 | g1.random().should.be.exactly(g2.random()); 27 | } 28 | }); 29 | 30 | it('Should roughly match Python when seeded by array', function() { 31 | var seed1 = 0; 32 | var seed2 = 42; 33 | 34 | var g1 = new MersenneTwister([seed1]); 35 | var g2 = new MersenneTwister([seed2]); 36 | 37 | /* We should get a near exact match with Python's rng 38 | * when we seed by array. The code for generating 39 | * these comparison values is something like: 40 | 41 | import random 42 | 43 | r = random.Random(0) 44 | 45 | for i in range(10000000): 46 | x = r.random() 47 | if i % 1000000 == 0: print(x) 48 | */ 49 | var values1 = [0.84442, 0.34535, 0.25570, 0.32368, 0.89075]; 50 | var values2 = [0.63942, 0.55564, 0.55519, 0.81948, 0.94333]; 51 | 52 | for (var i = 0; i < 5000000; i++) { 53 | var rval1 = g1.random_long(); 54 | var rval2 = g2.random_long(); 55 | 56 | if (i % 1000000 == 0) { 57 | var idx = i / 1000000; 58 | rval1.should.be.approximately(values1[idx], 1e-5); 59 | rval2.should.be.approximately(values2[idx], 1e-5); 60 | } 61 | } 62 | }); 63 | }); 64 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "random-array-generator", 3 | "version": "1.0.7", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "mersenne-twister": { 8 | "version": "1.1.0", 9 | "resolved": "https://registry.npmjs.org/mersenne-twister/-/mersenne-twister-1.1.0.tgz", 10 | "integrity": "sha1-+RZhjuQ9cXnvz2Qb7EUx65Zwl4o=" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "random-array-generator", 3 | "version": "1.0.8", 4 | "description": "Generates an array of unique random numbers using a Mersene-twister algorithm.", 5 | "main": "./lib/generator.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "dependencies": { 10 | "mersenne-twister": "latest" 11 | }, 12 | "keywords": [ 13 | "random", 14 | "array", 15 | "mersenne-twister", 16 | "unique", 17 | "generate" 18 | ], 19 | "author": "Willie Potgieter ", 20 | "license": "MIT", 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/williepot/random-array-generator" 24 | } 25 | } 26 | --------------------------------------------------------------------------------