Skip to content

Instantly share code, notes, and snippets.

@iczero
Last active November 2, 2018 18:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iczero/67fbbabbebfb337b5a9a007fe67d693d to your computer and use it in GitHub Desktop.
Save iczero/67fbbabbebfb337b5a9a007fe67d693d to your computer and use it in GitHub Desktop.
an implementation of the rand() function of TI calculators in javascript
// generate TI random values and seeds
const mod1 = 2147483563;
const mod2 = 2147483399;
const mult1 = 40014;
const mult2 = 40692;
/**
* Check whether two arrays are equal to each other
* @param {Array} arr1
* @param {Array} arr2
* @return {Boolean}
*/
function checkArrayEquality(arr1, arr2) {
if (arr1.length !== arr2.length) return false;
for (let i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i]) return false;
}
return true;
}
/** Random generator class */
class RandomGenerator {
/**
* @param {Number[]|Number} seed The seed
*/
constructor(seed) {
if (!seed) {
this.seed = [12345, 67890]; // this is the default seed
} else if (seed instanceof Array) {
this.seed = seed;
} else {
this.seed = [(mult1 * seed) % mod1, seed % mod2];
}
}
/**
* Generate a single random value
* @return {Number}
*/
generate() {
this.seed = [(this.seed[0] * mult1) % mod1, (this.seed[1] * mult2) % mod2];
let result = (this.seed[0] - this.seed[1]) / mod1;
if (result < 0) result += 1;
return result;
}
/**
* Generate random integers
* @param {Number} low Lower limit
* @param {Number} high Upper limit
* @param {Number} num Count
* @return {Number[]}
*/
genInt(low, high, num = 1) {
let ret = Array(num).fill(0);
ret = ret.map(() => {
let num = this.generate();
return Math.floor(num * (high - low + 1) + low);
});
if (num === 1) return ret[0];
return ret;
}
/**
* Match an array of random integers
* @param {Number[]} matchArr Array to match
* @param {Number} low Lower limit for integers
* @param {Number} high Upper limit for integers
* @return {Number} The seed from which the array was generated
*/
findSeed(matchArr, low, high) {
// if low/high are defined then it uess genInt otherwise plain generate()
let arr = [];
let gen;
if (!high) gen = this.generate;
else gen = () => this.genInt(low, high);
for (;;) {
if (arr.length >= matchArr.length) arr.shift();
arr.push(gen());
console.log('checking', arr, 'against', matchArr);
if (checkArrayEquality(arr, matchArr)) {
console.log('found:', this.seed);
return this.seed;
}
}
}
}
module.exports = RandomGenerator;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment