Created
February 4, 2026 18:20
-
-
Save cemdrk/f5b40cdf882d24183318ca03774d4e87 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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