golcg/main.go
2024-01-14 17:48:59 -06:00

84 lines
2.1 KiB
Go

// 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 <seed> <shard_count>")
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))
}