Skip to content

Instantly share code, notes, and snippets.

@UMU18
Created May 27, 2025 05:19
Show Gist options
  • Save UMU18/52afe1e802c97eef7fa66915e4a867b4 to your computer and use it in GitHub Desktop.
Save UMU18/52afe1e802c97eef7fa66915e4a867b4 to your computer and use it in GitHub Desktop.
program to determines how many divisors each number between 1 and N
package main
import (
"bufio"
"fmt"
"math"
"os"
"runtime"
"sort"
"strconv"
"strings"
"sync"
)
type result struct {
number int
count int
}
func countDivisorsPerChunk(start, end, chunkID int, resultMap map[int][]result, mutex *sync.Mutex, wg *sync.WaitGroup, progress *int, totalBlocks int, progressMutex *sync.Mutex) {
defer wg.Done()
blockResults := make([]result, 0, end-start+1)
for num := start; num <= end; num++ {
count := 0
sqrt := int(math.Sqrt(float64(num)))
for i := 1; i <= sqrt; i++ {
if num%i == 0 {
count += 2
if i*i == num {
count-- // perfect square
}
}
}
blockResults = append(blockResults, result{number: num, count: count})
}
mutex.Lock()
resultMap[chunkID] = blockResults
mutex.Unlock()
// Update progress
progressMutex.Lock()
*progress++
fmt.Printf("Progress: %.2f%% (%d/%d blocks done)\n", float64(*progress)*100/float64(totalBlocks), *progress, totalBlocks)
progressMutex.Unlock()
}
func countDivisorsParallel(N int, chunkSize int, fileName string) error {
numCPU := runtime.NumCPU()
runtime.GOMAXPROCS(numCPU)
var wg sync.WaitGroup
mutex := &sync.Mutex{}
resultMap := make(map[int][]result)
totalBlocks := (N + chunkSize - 1) / chunkSize
progress := 0
progressMutex := &sync.Mutex{}
chunkID := 0
for start := 1; start <= N; start += chunkSize {
end := min(start+chunkSize-1, N)
wg.Add(1)
go countDivisorsPerChunk(start, end, chunkID, resultMap, mutex, &wg, &progress, totalBlocks, progressMutex)
chunkID++
}
wg.Wait()
file, err := os.Create(fileName)
if err != nil {
return err
}
defer file.Close()
// Sort and write
keys := make([]int, 0, len(resultMap))
for k := range resultMap {
keys = append(keys, k)
}
sort.Ints(keys)
evenNum := 0
for _, k := range keys {
for _, res := range resultMap[k] {
_, err := fmt.Fprintf(file, "%d -> %d\n", res.number, res.count)
if res.count%2 == 0 {
evenNum += 1
}
if err != nil {
return err
}
}
}
_, err = fmt.Fprintf(file, "Count Special Number = %d\n", evenNum)
return nil
}
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter the value of N: ")
nStr, _ := reader.ReadString('\n')
nStr = strings.TrimSpace(nStr)
N, err := strconv.Atoi(nStr)
if err != nil || N <= 0 {
fmt.Println("Invalid input for N")
return
}
chunkSize := 500000 // chunk size
outputFile := fmt.Sprintf("divisors_for_%d.txt", N)
err = countDivisorsParallel(N, chunkSize, outputFile)
if err != nil {
fmt.Println("Error:", err)
}
fmt.Printf("Done!!!,\nResults in: %s\n", outputFile)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment