Skip to content
Snippets Groups Projects
random.js 2.51 KiB
Newer Older
  • Learn to ignore specific revisions
  • kopareigns's avatar
    kopareigns committed
    /**
     * generate two independent Gaussian numbers using Box-Muller transform.
     * mean and deviation specify the desired mean and standard deviation.
    
    Arkerthan's avatar
    Arkerthan committed
     * @param {number} [mean]
     * @param {number} [deviation]
    
    kopareigns's avatar
    kopareigns committed
     * @returns {number[]}
     */
    
    Skriv's avatar
    Skriv committed
    function gaussianPair(mean = 0, deviation = 1) {
    
    kopareigns's avatar
    kopareigns committed
    	const r = Math.sqrt(-2.0 * Math.log(1 - Math.random()));
    	const sigma = 2.0 * Math.PI * (1 - Math.random());
    	return [r * Math.cos(sigma), r * Math.sin(sigma)].map(val => val * deviation + mean);
    
    Skriv's avatar
    Skriv committed
    }
    
    kopareigns's avatar
    kopareigns committed
    
    
    Arkerthan's avatar
    Arkerthan committed
    /**
     * Generate a random integer with a normal distribution between min and max (both inclusive).
     * Default parameters result in truncating the standard normal distribution between -3 and +3.
     * Not specifying min/max results in rerolling val approximately 0.3% of the time.
     * @param {number} [mean]
     * @param {number} [deviation]
     * @param {number} [min]
     * @param {number} [max]
     * @returns {number}
     */
    
    Skriv's avatar
    Skriv committed
    function normalRandInt(mean = 0, deviation = 1, min = mean - 3 * deviation, max = mean + 3 * deviation) {
    
    kopareigns's avatar
    kopareigns committed
    	let val = gaussianPair(mean, deviation)[0];
    	while (val < min || val > max) {
    		val = gaussianPair(mean, deviation)[0];
    	}
    	return Math.round(val);
    
    Skriv's avatar
    Skriv committed
    }
    
    kopareigns's avatar
    kopareigns committed
    
    /**
     * Returns a random integer between min and max (both inclusive).
     * If count is defined, chooses that many random numbers between min and max and returns the average. This is an approximation of a normal distribution.
     * @param {number} min
     * @param {number} max
    
    Arkerthan's avatar
    Arkerthan committed
     * @param {number} [count]
    
    kopareigns's avatar
    kopareigns committed
     * @returns {number}
     */
    
    Skriv's avatar
    Skriv committed
    function jsRandom(min, max, count = 1) {
    
    kopareigns's avatar
    kopareigns committed
    	function rand() {
    		return Math.random() * (max - min + 1) + min;
    	}
    
    	if (count === 1) {
    		return Math.floor(rand());
    	}
    
    	let total = 0;
    	for (let i = 0; i < count; i++) {
    		total += rand();
    	}
    
    Skriv's avatar
    Skriv committed
    	return Math.floor(total / count);
    
    Skriv's avatar
    Skriv committed
    }
    
    kopareigns's avatar
    kopareigns committed
    
    /**
     * Chooses multiple random elements of an array.
     * @param {number[]} arr
     * @param {number} count
     * @returns {number[]}
     */
    
    Skriv's avatar
    Skriv committed
    function jsRandomMany(arr, count) {
    
    kopareigns's avatar
    kopareigns committed
    	let result = [];
    	let _tmp = arr.slice();
    	for (let i = 0; i < count; i++) {
    		let index = Math.floor(Math.random() * _tmp.length);
    		result.push(_tmp.splice(index, 1)[0]);
    	}
    	return result;
    
    Skriv's avatar
    Skriv committed
    }
    
    kopareigns's avatar
    kopareigns committed
    
    /**
     * Accepts both an array and a list, returns undefined if nothing is passed.
    
    Skriv's avatar
    Skriv committed
     * @param {any[]} choices
    
    Arkerthan's avatar
    Arkerthan committed
     * @param {any} [otherChoices]
    
    Skriv's avatar
    Skriv committed
     * @returns {any}
    
    kopareigns's avatar
    kopareigns committed
     */
    
    Skriv's avatar
    Skriv committed
    function jsEither(choices, ...otherChoices) {
    
    kopareigns's avatar
    kopareigns committed
    	if (otherChoices.length === 0 && Array.isArray(choices)) {
    		return choices[Math.floor(Math.random() * choices.length)];
    	}
    	const allChoices = otherChoices;
    	allChoices.push(choices);
    	return allChoices[Math.floor(Math.random() * allChoices.length)];
    
    Skriv's avatar
    Skriv committed
    }