Integer range specification
kripod opened this issue · comments
seedrandom('seed').int32(0, 5)
should return a value between 0 (inclusive) and 5 (exclusive): 0, 1, 2, 3, 4. I have already implemented the functionality myself, but feel that this should be a built-in method.
/**
* A randomization engine which can be made deterministic by using a
* custom-seeded engine.
*/
export default class Randomizer {
/**
* Engine to be used for randomization.
* @type {Object}
*/
engine;
constructor(engine) {
this.engine = engine;
}
/**
* Returns a random 32-bit integer (signed or unsigned) in the given range.
* @param {number} min Minimum value (included).
* @param {number} max Maximum value (excluded).
* @returns {number}
*/
getInt(min, max) {
const range = max - min;
// Get the lowest integer which is not part of the equal distribution range
const firstTooHighValue =
Config.UINT32_RANGE - Config.UINT32_RANGE % range;
let result;
do {
// Generate a random 32-bit unsigned integer
result = this.engine.int32() - Config.INT32_MIN_VALUE;
} while (
// Ensure equal distribution
result >= firstTooHighValue
);
// Place the result in the range and offset it by the minimum value
return result % range + min;
}
/**
* Shuffles the elements of an array.
* @param {Object[]} array Array to be shuffled.
* @returns {Object[]}
*/
shuffleArray(array) {
const result = [...array];
// Perform Durstenfeld shuffle
for (let i = array.length - 1; i > 0; --i) {
// Generate a random integer in [0, i] deterministically
const j = this.getInt(0, i);
// Swap result[i] and result[j]
[result[i], result[j]] = [result[j], result[i]];
}
return result;
}
}
In the spirit of keeping this library as small as possible, I think we should consider convenience functions "out of scope" - there are a large number of convenience functions that should be supplied by a full random number library: uniform, normal, exponential, integer ranges, shuffles, etc. We just provide raw access to a PRNG source and leave it to other libraries to supply more specific distributions.