Created
May 27, 2025 05:19
-
-
Save UMU18/52afe1e802c97eef7fa66915e4a867b4 to your computer and use it in GitHub Desktop.
program to determines how many divisors each number between 1 and N
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
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