Skip to content

Instantly share code, notes, and snippets.

@dlmanning
Last active June 19, 2022 18:43
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 dlmanning/cee11742c1c634222e2ecd294fc746fe to your computer and use it in GitHub Desktop.
Save dlmanning/cee11742c1c634222e2ecd294fc746fe to your computer and use it in GitHub Desktop.
Calculate odds of recombinators
mods \ total mods in pool
desired \______________________________________________
| 1 | 2 | 3 | 4 | 5 | 6 |
-------------|-------|-------|-------|-------|-------|-------
1 | 0.667 | 0.667 | 0.633 | 0.563 | 0.500 | 0.450 |
-------------|-------|-------|-------|-------|-------|-------
2 | 0.000 | 0.333 | 0.367 | 0.267 | 0.200 | 0.160 |
-------------|-------|-------|-------|-------|-------|-------
3 | 0.000 | 0.000 | 0.200 | 0.087 | 0.050 | 0.035 |
const probToPickNMods =[
[0, 0, 0, 0],
[1/3, 2/3, 0, 0],
[0, 2/3, 1/3, 0],
[0, 0.3, 0.5, 0.2],
[0, 0.1, 0.55, 0.35],
[0, 0, 0.5, 0.5],
[0, 0, 0.30, 0.70]
]
/**
* probailityOfSuccess
*
* @param {number} modsToAdd
* @param {number} desiredMods
* @param {number} totalMods
* @returns {number}
*
* The number of ways to pick 'k' desired mods from a pool of 'n' in 'm' selections
* is the same as the number of ways to pick `m - k` mods from a pool of `n - k` mods
*
* Example:
*
* The number of subsets of { A, B, C, D } containing 3 items, of which two are A an B is the same as
* the number of subsets of { C, D } containing 1 item, or (n - k)C(m - k) where (k = 2, n = 4, m = 3).
*
* or 2!/(2 - 1)!1! = 2
*
* A B C D C D
*
* A B C <-- good C
* A B D <-- good D
* A C D *
* B C D *
*/
function probabilityOfSucccess(modsToAdd, desiredMods, totalMods) {
if (modsToAdd < desiredMods) {
return 0;
}
const badMods = totalMods - desiredMods;
// Number of ways to select a set of size of the number of mods we're going to add that you don't care about from the set
// of bad mods, where order isn't important.
const num = factorial(badMods) / (factorial(badMods - (modsToAdd - desiredMods)) * factorial((modsToAdd - desiredMods)));
// Just the total number of ways to select a set of k mods from a pool of size n where order doesn't matter.
const denom = factorial(totalMods) / (factorial(totalMods - modsToAdd) * factorial(modsToAdd));
return num / denom;
}
function recomb (modsToKeep, totalMods) {
if (!(Number.isInteger(modsToKeep) && modsToKeep > 0 && modsToKeep < 4)) {
throw new Error('First parameter must be 1, 2 or 3');
}
if (!(Number.isInteger(totalMods) && totalMods > 0 && totalMods < 7)) {
throw new Error('Second parameter must be an integer between 1 and 6.');
}
let probabilityToPickNMods = probToPickNMods[totalMods];
let success = 0;
for (let i = 1; i < probabilityToPickNMods.length; i++) {
if (probabilityToPickNMods[i] > 0) {
const prob = probabilityOfSucccess(i, modsToKeep, totalMods);
success += prob * probabilityToPickNMods[i];
}
}
return success;
}
function output() {
console.log(
`
mods \\ total mods in pool
desired \\______________________________________________
| 1 | 2 | 3 | 4 | 5 | 6 |`);
for (let i = 1; i <= 3; i++) {
console.log(`-------------|-------|-------|-------|-------|-------|-------`)
let line = ` ${i} `;
for (let j = 1; j <= 6; j++) {
const prob = recomb(i, j);
line += ` | ${prob.toFixed(3)}`;
}
console.log(line + ' |');
}
}
output();
function factorial (n) {
while (n > 1) {
return n * factorial(n - 1);
}
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment