You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
1.1 KiB
Go
68 lines
1.1 KiB
Go
5 years ago
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"bufio"
|
||
|
"strconv"
|
||
|
"runtime"
|
||
|
)
|
||
|
|
||
|
var ch chan uint64
|
||
|
|
||
|
func check(e error) {
|
||
|
if e != nil {
|
||
|
panic(e)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
ch = make(chan uint64)
|
||
|
numThreads := runtime.NumCPU()
|
||
|
fmt.Printf("Starting to calculate primes\n")
|
||
|
f, err := os.OpenFile("primes.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||
|
check(err)
|
||
|
defer f.Close()
|
||
|
w := bufio.NewWriter(f)
|
||
|
defer w.Flush()
|
||
|
start := uint64(1)
|
||
|
if len(os.Args) >= 2 {
|
||
|
start, err = strconv.ParseUint(os.Args[1], 10, 64)
|
||
|
check(err)
|
||
|
}
|
||
|
if start % 2 == 0 {
|
||
|
start += 1
|
||
|
}
|
||
|
for i := 0; i < numThreads; i++ {
|
||
|
go getPrimes(start + uint64(i * 2), uint64(numThreads * 2))
|
||
|
}
|
||
|
for {
|
||
|
prime := <- ch
|
||
|
fmt.Printf("%d\n", prime)
|
||
|
w.WriteString(strconv.FormatUint(prime, 10) + "\n")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// coroutine that calculates primes and adds it to the channel
|
||
|
func getPrimes(start, incr uint64) {
|
||
|
num := uint64(start)
|
||
|
for {
|
||
|
isPrime := true
|
||
|
if (num < 3 || num % 2 == 0) {
|
||
|
isPrime = false
|
||
|
num += incr
|
||
|
continue
|
||
|
}
|
||
|
var i uint64
|
||
|
for i = 3; i < num/2; i+=2 {
|
||
|
if num % i == 0 {
|
||
|
isPrime = false
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
if isPrime {
|
||
|
ch <- num
|
||
|
}
|
||
|
num += incr
|
||
|
}
|
||
|
}
|