Implement primes counter in go
This commit is contained in:
commit
a49dc188e0
4 changed files with 102 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
.idea
|
||||
go-primes-counter
|
6
README.md
Normal file
6
README.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Primes counter
|
||||
````shell
|
||||
go build
|
||||
./go-primes-counter -h
|
||||
./go-primes-counter -start 10 -max 1000 -print-count -1 -step-size 100
|
||||
````
|
3
go.mod
Normal file
3
go.mod
Normal file
|
@ -0,0 +1,3 @@
|
|||
module go-primes-counter
|
||||
|
||||
go 1.16
|
91
main.go
Normal file
91
main.go
Normal file
|
@ -0,0 +1,91 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func main() {
|
||||
start, max, step, printCount := parseArgs()
|
||||
if max < start {
|
||||
start, max = max, start
|
||||
}
|
||||
totalLength := max - start
|
||||
if totalLength < step {
|
||||
step = totalLength
|
||||
}
|
||||
|
||||
// Start jobs
|
||||
var wg sync.WaitGroup
|
||||
results := make(chan int, 100)
|
||||
for i := start; i < max; i += step {
|
||||
wg.Add(1)
|
||||
go worker(i, i+step, &wg, results)
|
||||
}
|
||||
|
||||
// Collect results
|
||||
go waitForWorkers(&wg, results)
|
||||
var primes []int
|
||||
for prime := range results {
|
||||
primes = append(primes, prime)
|
||||
}
|
||||
|
||||
// Print results
|
||||
fmt.Println("There are", len(primes), "primes between", start, "and", max)
|
||||
if printCount > len(primes) {
|
||||
printCount = -1
|
||||
}
|
||||
if printCount < 0 {
|
||||
fmt.Println("Here they are:")
|
||||
fmt.Println(primes)
|
||||
} else {
|
||||
fmt.Println("Here's a free sample:")
|
||||
fmt.Println(primes[:printCount])
|
||||
}
|
||||
}
|
||||
|
||||
func worker(start, end int, wg *sync.WaitGroup, results chan<- int) {
|
||||
defer wg.Done()
|
||||
for i := start; i < end; i++ {
|
||||
if IsPrime(i) {
|
||||
results <- i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func waitForWorkers(wg *sync.WaitGroup, results chan int) {
|
||||
wg.Wait()
|
||||
close(results)
|
||||
}
|
||||
|
||||
// IsPrime determines if the given int is a prime number or not.
|
||||
// The method currently implemented by this method is not smart and not
|
||||
// optimized for large numbers.
|
||||
func IsPrime(n int) bool {
|
||||
if n <= 3 {
|
||||
return n > 1
|
||||
}
|
||||
if n%2 == 0 || n%3 == 0 {
|
||||
return false
|
||||
}
|
||||
i := 5
|
||||
for i*i <= n {
|
||||
if n%i == 0 || n%(i+2) == 0 {
|
||||
return false
|
||||
}
|
||||
i += 6
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func parseArgs() (int, int, int, int) {
|
||||
start := flag.Int("start", 0, "The start number")
|
||||
max := flag.Int("max", 10_000, "The end value")
|
||||
step := flag.Int("step-size", 1_000, "The job size")
|
||||
printCountDesc := `Number of primes to print. -1 to print all.
|
||||
Primes are not guaranteed to be sorted.`
|
||||
printCount := flag.Int("print-count", 20, printCountDesc)
|
||||
flag.Parse()
|
||||
return *start, *max, *step, *printCount
|
||||
}
|
Loading…
Reference in a new issue