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