Skip to content

Instantly share code, notes, and snippets.

@hrueger
Last active August 28, 2022 19:29
Show Gist options
  • Save hrueger/530752e5115d0ff1c8c0133af7b081c9 to your computer and use it in GitHub Desktop.
Save hrueger/530752e5115d0ff1c8c0133af7b081c9 to your computer and use it in GitHub Desktop.
const rounds = 100000000;
import cluster from 'node:cluster';
import { cpus } from 'node:os';
import process from 'node:process';
const numCPUs = cpus().length;
const roundsPerCPU = Math.round(rounds / numCPUs);
if (cluster.isPrimary) {
console.log(`Primary ${process.pid} is running`);
// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
const start = Date.now();
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} finished`);
});
let results: number[] = [];
let remaining = numCPUs;
for (const id in cluster.workers) {
cluster.workers[id]!.on('message', (result: number[]) => {
results = results.concat(result)
remaining--;
if (remaining === 0) {
const avg = results.reduce((a, b) => a + b, 0) / results.length;
console.log("------------------");
console.log(`Average is ${avg} for ${results.length} rounds. Calculated in ${Math.round(((Date.now() - start) / 1000) * 100) / 100}s using ${numCPUs} CPUs.`);
process.exit();
}
});
}
} else {
console.log(`Worker ${process.pid} started`);
const result = rollTheDice(roundsPerCPU);
process.send?.(result);
}
function rollTheDice(rounds: number) {
const takesPerRound: number[] = [];
const DICES = 5;
for (let round = 0; round < rounds; round++) {
let diceLeft = 5;
let takes = 0;
let targetNumber: number | undefined = undefined;
while (diceLeft > 0) {
takes++;
const results: number[] = [];
if (targetNumber !== undefined) {
for (let i = 0; i < DICES - diceLeft; i++) {
results.push(targetNumber);
}
}
for (let dice = 0; dice < diceLeft; dice++) {
results.push(Math.round(Math.random() * 6));
}
targetNumber = mode(results);
diceLeft = results.filter((a) => a !== targetNumber).length;
}
takesPerRound[round] = takes;
// console.log(`Round #${round + 1} took ${takes}`);
}
return takesPerRound;
}
function mode<T>(arr: T[]): T {
return arr.sort((a,b) =>
arr.filter(v => v===a).length
- arr.filter(v => v===b).length
).pop()!;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment