Skip to content

Instantly share code, notes, and snippets.

@Incognito
Last active August 3, 2020 07:33
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 Incognito/594dba74b4372f9edd8c4f5eb7452cb4 to your computer and use it in GitHub Desktop.
Save Incognito/594dba74b4372f9edd8c4f5eb7452cb4 to your computer and use it in GitHub Desktop.
random-without-winning-streaks
node_modules
const seedrandom = require('seedrandom'); // Because JS doesn't let you set the seed on Math.random.
const { WebClient } = require('@slack/web-api');
const util = require('util');
const fs = require('fs');
const readFile = util.promisify(fs.readFile);
const writeFile = util.promisify(fs.writeFile);
let candidates = [
"Xiao Yu'er",
"Hua Wu Que",
"Tie Xin Lan",
"Su Ying",
];
const prngFile = '/tmp/prng.tmp';
async function loadPrngStateFile() {
return await readFile(prngFile, 'utf8')
.then(JSON.parse)
.catch(()=>{return createRngWithSeed("something")});
}
function createRngWithSeed(seed) {
const prng = seedrandom(seed, {state: true});
const p = seedrandom("", {state: prng.state});
return prng.state();
}
function selectCandidate(random) {
return candidates[Math.floor(random * candidates.length)];
}
function selectNextCandidate(prng, lastCandidate) {
let nextCandidateState = prng.state(); // "next", because prng() was called.
let nextCandidate = selectCandidate(prng());
const next = {
candidate: nextCandidate,
state: nextCandidateState
};
// Prevents "streaks".
while (lastCandidate === next.candidate) {
next.state = prng.state();
next.candidate = selectCandidate(prng());
}
return next;
}
// Fyi: This function is async, so be sure to call it sequentially if you put
// this into an array.
async function main() {
const initialPrngState = await loadPrngStateFile()
const prng = seedrandom("", {state: initialPrngState});
let lastCandidate = selectCandidate(prng());
let next = selectNextCandidate(prng, lastCandidate)
await writeFile(prngFile, JSON.stringify(next.state), 'utf8');
// return next.candidate;
}
main();
/*
No streaks.
However, it has a slightly uneven distribution after 1000 runs
{
'0': 103, // **********
'1': 103, // **********
'2': 89, // ********
'3': 108, // **********
'4': 107, // **********
'5': 98, // *********
'6': 103, // **********
'7': 87, // ********
'8': 97, // *********
'9': 105 // **********
}
*/
{
"name": "less-annoying-rand",
"version": "0.1.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@slack/logger": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@slack/logger/-/logger-2.0.0.tgz",
"integrity": "sha512-OkIJpiU2fz6HOJujhlhfIGrc8hB4ibqtf7nnbJQDerG0BqwZCfmgtK5sWzZ0TkXVRBKD5MpLrTmCYyMxoMCgPw==",
"requires": {
"@types/node": ">=8.9.0"
}
},
"@slack/types": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/@slack/types/-/types-1.7.0.tgz",
"integrity": "sha512-aigLPmTO513JxeFyeII/74y+S5jU39tabDWPsZyMHJWCYqK3vCkRvV73NL+Ay+Tq5RC2NgSmkedk1wvQJ6oXLg=="
},
"@slack/web-api": {
"version": "5.11.0",
"resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-5.11.0.tgz",
"integrity": "sha512-4a/uj7IZjFLu7Qmq0nH74ecLqk1iI/9x3yRS/v6M5vXDyc5lEruRFp4d5/bz4eN5Bathlq4Bws0wioY516fPag==",
"requires": {
"@slack/logger": ">=1.0.0 <3.0.0",
"@slack/types": "^1.7.0",
"@types/is-stream": "^1.1.0",
"@types/node": ">=8.9.0",
"@types/p-queue": "^2.3.2",
"axios": "^0.19.0",
"eventemitter3": "^3.1.0",
"form-data": "^2.5.0",
"is-stream": "^1.1.0",
"p-queue": "^2.4.2",
"p-retry": "^4.0.0"
}
},
"@types/is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@types/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha512-jkZatu4QVbR60mpIzjINmtS1ZF4a/FqdTUTBeQDVOQ2PYyidtwFKr0B5G6ERukKwliq+7mIXvxyppwzG5EgRYg==",
"requires": {
"@types/node": "*"
}
},
"@types/node": {
"version": "14.0.27",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.27.tgz",
"integrity": "sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g=="
},
"@types/p-queue": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/@types/p-queue/-/p-queue-2.3.2.tgz",
"integrity": "sha512-eKAv5Ql6k78dh3ULCsSBxX6bFNuGjTmof5Q/T6PiECDq0Yf8IIn46jCyp3RJvCi8owaEmm3DZH1PEImjBMd/vQ=="
},
"@types/retry": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA=="
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"axios": {
"version": "0.19.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
"requires": {
"follow-redirects": "1.5.10"
}
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
}
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"eventemitter3": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
"integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q=="
},
"follow-redirects": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
"requires": {
"debug": "=3.1.0"
}
},
"form-data": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
"integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.6",
"mime-types": "^2.1.12"
}
},
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
},
"mime-db": {
"version": "1.44.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
"integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
},
"mime-types": {
"version": "2.1.27",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
"integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
"requires": {
"mime-db": "1.44.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"p-queue": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/p-queue/-/p-queue-2.4.2.tgz",
"integrity": "sha512-n8/y+yDJwBjoLQe1GSJbbaYQLTI7QHNZI2+rpmCDbe++WLf9HC3gf6iqj5yfPAV71W4UF3ql5W1+UBPXoXTxng=="
},
"p-retry": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.2.0.tgz",
"integrity": "sha512-jPH38/MRh263KKcq0wBNOGFJbm+U6784RilTmHjB/HM9kH9V8WlCpVUcdOmip9cjXOh6MxZ5yk1z2SjDUJfWmA==",
"requires": {
"@types/retry": "^0.12.0",
"retry": "^0.12.0"
}
},
"retry": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs="
},
"seedrandom": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
"integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="
}
}
}
{
"name": "less-annoying-rand",
"version": "0.1.0",
"description": "Making Random draws less annoying",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@slack/web-api": "^5.11.0",
"seedrandom": "^3.0.5"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment