// linear congruential generator written in go // by darkmage // https://www.evildojo.com // https://www.twitter.com/evildojo666 package main import ( "fmt" "time" "os" "math" "math/rand" "strconv" "sync" ) // define a global sieve var sieve []bool var wg sync.WaitGroup func run_sieve(max int64, start int64, move int64, shard_num int64, shard_count int64) { var current int64 = start + shard_num if current > max-1 { current = current % max } for i := int64(0); i <= max/shard_count; i++ { sieve[current] = true current = current + move if current > max-1 { current = current % max } } defer wg.Done() } func main() { if len(os.Args) != 3 { fmt.Println("Usage: go run main.go ") os.Exit(1) } seed, err := strconv.ParseInt(os.Args[1], 10, 64) if err != nil { fmt.Println("Error: ", err) os.Exit(1) } rand := rand.New(rand.NewSource(seed)) var max int64 = 256*256*256*256 var start int64 = rand.Int63n(max) fmt.Println("start:", start) shard_count, err := strconv.ParseInt(os.Args[2], 10, 64) if err != nil { fmt.Println("Error: ", err) os.Exit(1) } fmt.Println("shard_count:", shard_count) var move int64 = (int64(math.Sqrt(float64(max))) + 1) * shard_count fmt.Println("move:", move) sieve = make([]bool, max) start_time := time.Now() for i := int64(0); i < shard_count; i++ { fmt.Println("shard:", i) wg.Add(1) go run_sieve(max, start, move, i, shard_count) } wg.Wait() end_time := time.Now() fmt.Println("Completed iterating numbers") fmt.Println("Time elapsed:", end_time.Sub(start_time)) fmt.Println("Checking sieve") start_time = time.Now() for i := int64(0); i < max; i++ { if !sieve[i] { fmt.Println(os.Stderr, "Error, not all numbers flipped") os.Exit(1) } } end_time = time.Now() fmt.Println("Time elapsed:", end_time.Sub(start_time)) }