Skip to content

Instantly share code, notes, and snippets.

@kashav
Created September 1, 2018 18:43
Show Gist options
  • Save kashav/2aa93206b127984779a07a781c9a80aa to your computer and use it in GitHub Desktop.
Save kashav/2aa93206b127984779a07a781c9a80aa to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"math"
"math/big"
"os"
"strconv"
)
func numThreads(n int64) int64 {
if n <= 5000 {
return 2
}
return 8 * int64(math.Log2(float64(n)))
}
func prodNToM(n int64, m int64, c chan *big.Int) {
var net = new(big.Int)
net.MulRange(n, m)
c <- net
}
func min(a int64, b int64) int64 {
if a > b {
return b
}
return a
}
func reduce(a *big.Int, b *big.Int, c chan *big.Int) {
a.Mul(a, b)
c <- a
}
func Factorial(i int64) *big.Int {
var n, parts, d int64
parts = 0
d = i / numThreads(i)
c := make(chan *big.Int)
for n = 1; n <= i; n += min(i-n+1, d+1) {
go prodNToM(n, min(i, n+d), c)
parts++
}
for parts > 1 {
for n = 0; n < parts; n += 2 {
go reduce(<-c, <-c, c)
}
parts >>= 1
}
return <-c
}
func main() {
i, err := strconv.ParseInt(os.Args[1], 10, 64)
if err != nil {
panic(err)
}
fmt.Println(Factorial(i))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment