Skip to content

Instantly share code, notes, and snippets.

@cemdrk
Created February 4, 2026 18:20
Show Gist options
  • Select an option

  • Save cemdrk/f5b40cdf882d24183318ca03774d4e87 to your computer and use it in GitHub Desktop.

Select an option

Save cemdrk/f5b40cdf882d24183318ca03774d4e87 to your computer and use it in GitHub Desktop.
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
const os = require('os');
if (isMainThread) {
// Main thread
const NUM_WORKERS = os.cpus().length;
const START = 100;
const END = 100_000_000;
const CHUNK_SIZE = Math.ceil((END - START) / NUM_WORKERS);
const globalSeen = {};
const globalReachedNums = new Set();
let completedWorkers = 0;
console.log(`Starting ${NUM_WORKERS} workers...`);
console.log(`Range: ${START} to ${END}`);
console.time('Total time');
for (let i = 0; i < NUM_WORKERS; i++) {
const rangeStart = START + i * CHUNK_SIZE;
const rangeEnd = Math.min(rangeStart + CHUNK_SIZE, END);
const worker = new Worker(__filename, {
workerData: { rangeStart, rangeEnd, workerId: i + 1 }
});
worker.on('message', ({ seen, reachedNums, workerId }) => {
console.log(`Worker ${workerId} completed`);
// Merge results
for (const [key, value] of Object.entries(seen)) {
if (key in globalSeen) {
globalSeen[key].push(...value);
} else {
globalSeen[key] = value;
}
}
reachedNums.forEach(num => globalReachedNums.add(num));
});
worker.on('error', err => console.error(`Worker ${i + 1} error:`, err));
worker.on('exit', () => {
completedWorkers++;
if (completedWorkers === NUM_WORKERS) {
console.timeEnd('Total time');
console.log('\nSeen:', globalSeen);
console.log('\nReached Nums:', globalReachedNums);
}
});
}
} else {
// Worker thread
const { rangeStart, rangeEnd, workerId } = workerData;
const maxNum = num => +[...`${num}`].sort((a, b) => b - a).join('');
const minNum = num => +[...`${num}`].sort((a, b) => a - b).join('');
const reachedNums = new Set();
const seen = {};
const MAX_STEP = 1_000_000;
const findKaprekar = (i, _min, _max, prev, step) => {
let diff = _max - _min;
while (diff) {
if (step > MAX_STEP) {
if (diff in seen) {
console.log(`[Worker ${workerId}] found`, i, diff, prev, step);
} else {
seen[diff] = [-i];
}
break;
}
if (diff in seen) {
break;
}
if (prev === diff) {
seen[diff] = [i];
reachedNums.add(prev);
break;
}
prev = diff;
diff = maxNum(diff) - minNum(diff);
step++;
}
};
console.log(`Worker ${workerId} processing range ${rangeStart} to ${rangeEnd}`);
for (let i = rangeStart; i < rangeEnd; i++) {
findKaprekar(i, minNum(i), maxNum(i), null, 1);
}
parentPort.postMessage({
seen,
reachedNums: [...reachedNums],
workerId
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment