Skip to content

Instantly share code, notes, and snippets.

@annibal
Last active December 3, 2025 13:09
Show Gist options
  • Select an option

  • Save annibal/a45ffd57e9ca6427297ad9999357cfd1 to your computer and use it in GitHub Desktop.

Select an option

Save annibal/a45ffd57e9ca6427297ad9999357cfd1 to your computer and use it in GitHub Desktop.
A way to check how random is your random function. Invokes it billions of times and counts each result for you.

Usage:

function myRandomFunction() {
  return Math.random() * 100 | 0;
}

const testRF = testRandomFunction({
  randFn: () => { myRandomFunction(); },
  runsPerCycle: 1e5,
  logProgress: true,
});

const { percent, count, total } = await testRF.results;

console.log(percent);
// 0: 0.956
// 1: 0.988
// 2: 1.041
// 3: 0.927
// 4: 0.983
// ...
// 98: 0.946
// 99: 1.059

Or use .then as preferred:

const outputDistribution = testRandomFunction({
  randFn: () => Math.random() * 1000 | 0;,
  runsPerCycle: 1e12,
  logProgress: false,
  })
  .results.then((res) => res.percent)
;

Theoretically it has an aborting mechanism:

const testObj = testRandomFunction({ randFn: () => someRandomFn })
// ...
    testObj.stopTest();
    // Requested immediate end of RandFn Test
;
function testRandomFunction(props) {
const { randFn, runsPerCycle = 1e5, logProgress = true } = (props || {});
if (typeof randFn !== "function") {
throw new TypeError("Random Function `randFn` must be a function in order to test");
}
const results = {}, startTime = Date.now(), strEllapsed = '', ret = {};
let stopped = false;
function clog(...args) {
if (logProgress) {
console.log(...args);
}
}
function getElapsedTime(currTime) {
const hms = [
[1000,"″","″"],[60,"′","′"],[60,"h","h"]
].reduce((a,c,i,w) => [
...a,
[w.slice(0,i+1).reduce((_a,_c)=>_a*_c[0],1), ...c.slice(1)]
], []).reverse()
;
return hms
.reduce((a,d) => [
[...a[0], a[1] / d[0] | 0], a[1] % d[0], [...a[2], [d[1],d[2]] ]
], [[], currTime - startTime, []])
.map((_,i,x) => [x[0][i], x[2][i][0], x[2][i][1] ] )
.reduce(
(a,[n,s,p],i,w) => a + (
(i === w.length - 1) ? " " : (i === 0 ? "" : " ")
) + n + "" + (n === 1 ? s : p)
, ""
)
;
}
results.count = {};
results.percent = {};
results.total = 0;
ret.results = new Promise((resolve, reject) => {
for (let l1 = 0; l1 <= 99; l1++) {
clog([
String(l1).padStart(3), "% [", (
"▓".repeat(l1 / 3 | 0) +
("_░▒".split(""))[ l1 % 3 ]
).padEnd(34, "_"),
"] ",
getElapsedTime(Date.now())
].join(""));
if (stopped) {
clog("RandFn Test was stopped");
return reject(results);
}
for (let l2=0; l2 <= runsPerCycle; l2++) {
try {
let out = randFn();
if (results.count[out] == null) {
results.count[out] = 0;
}
results.count[out] += 1;
results.total += 1;
} catch (e) {
clog("randFn failed during test, aborting");
console.trace(e);
return reject(results);
}
if (stopped) {
clog("RandFn Test was stopped");
return reject(results);
}
}
// end for 1
}
clog("RandFn test completed! Results of the test:", results);
resolve(results);
});
ret.stopTest = () => {
clog("Requested immediate end of RandFn Test");
stopped = true;
};
Object.entries(results.count).forEach(([key, value]) => {
results.percent[key] = Math.round(value / results.total * 1e5) / 1e3;
})
clog(`100% [${'▓'.repeat(34)}] ${strEllapsed}`);
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment