github.com/mitranim/gg@v0.1.17/rnd_test.go (about)

     1  package gg_test
     2  
     3  import (
     4  	cr "crypto/rand"
     5  	"fmt"
     6  	"io"
     7  	"math/big"
     8  	mr "math/rand"
     9  	"testing"
    10  
    11  	"github.com/mitranim/gg"
    12  	"github.com/mitranim/gg/gtest"
    13  )
    14  
    15  func rndSrc() io.Reader { return mr.New(mr.NewSource(0)) }
    16  
    17  func TestRandomInt_uint64(t *testing.T) {
    18  	defer gtest.Catch(t)
    19  
    20  	fun := gg.RandomInt[uint64]
    21  	src := rndSrc()
    22  
    23  	gtest.Eq(fun(src), 13906042503472976897)
    24  	gtest.Eq(fun(src), 14443988502964065089)
    25  	gtest.Eq(fun(src), 17196259562495758190)
    26  	gtest.Eq(fun(src), 8433884527138253544)
    27  	gtest.Eq(fun(src), 16185558041432496379)
    28  	gtest.Eq(fun(src), 15280578644808371633)
    29  	gtest.Eq(fun(src), 16279533959527364769)
    30  	gtest.Eq(fun(src), 5680856659213489233)
    31  	gtest.Eq(fun(src), 18012265314398557154)
    32  	gtest.Eq(fun(src), 12810001989293853876)
    33  	gtest.Eq(fun(src), 8828672906944723960)
    34  	gtest.Eq(fun(src), 11259781176380201387)
    35  	gtest.Eq(fun(src), 6266933393232556850)
    36  	gtest.Eq(fun(src), 8632501143404108278)
    37  	gtest.Eq(fun(src), 6856693871787269831)
    38  	gtest.Eq(fun(src), 6107792380522581863)
    39  }
    40  
    41  func TestRandomInt_int64(t *testing.T) {
    42  	defer gtest.Catch(t)
    43  
    44  	fun := gg.RandomInt[int64]
    45  	src := rndSrc()
    46  
    47  	gtest.Eq(fun(src), -4540701570236574719)
    48  	gtest.Eq(fun(src), -4002755570745486527)
    49  	gtest.Eq(fun(src), -1250484511213793426)
    50  	gtest.Eq(fun(src), 8433884527138253544)
    51  	gtest.Eq(fun(src), -2261186032277055237)
    52  	gtest.Eq(fun(src), -3166165428901179983)
    53  	gtest.Eq(fun(src), -2167210114182186847)
    54  	gtest.Eq(fun(src), 5680856659213489233)
    55  	gtest.Eq(fun(src), -434478759310994462)
    56  	gtest.Eq(fun(src), -5636742084415697740)
    57  	gtest.Eq(fun(src), 8828672906944723960)
    58  	gtest.Eq(fun(src), -7186962897329350229)
    59  	gtest.Eq(fun(src), 6266933393232556850)
    60  	gtest.Eq(fun(src), 8632501143404108278)
    61  	gtest.Eq(fun(src), 6856693871787269831)
    62  	gtest.Eq(fun(src), 6107792380522581863)
    63  }
    64  
    65  func BenchmarkRandomInt_true_random(b *testing.B) {
    66  	defer gtest.Catch(b)
    67  
    68  	for ind := 0; ind < b.N; ind++ {
    69  		gg.RandomInt[uint64](cr.Reader)
    70  	}
    71  }
    72  
    73  func BenchmarkRandomInt_pseudo_random(b *testing.B) {
    74  	defer gtest.Catch(b)
    75  	src := rndSrc()
    76  	b.ResetTimer()
    77  
    78  	for ind := 0; ind < b.N; ind++ {
    79  		gg.RandomInt[uint64](src)
    80  	}
    81  }
    82  
    83  func TestRandomIntBetween_uint64(t *testing.T) {
    84  	defer gtest.Catch(t)
    85  	testRandomUintBetween[uint64]()
    86  }
    87  
    88  func TestRandomIntBetween_int64(t *testing.T) {
    89  	defer gtest.Catch(t)
    90  	testRandomUintBetween[int64]()
    91  	testRandomSintBetween[int64]()
    92  }
    93  
    94  func testRandomUintBetween[A gg.Int]() {
    95  	fun := gg.RandomIntBetween[A]
    96  
    97  	gtest.PanicStr(`invalid range [0,0)`, func() {
    98  		fun(rndSrc(), 0, 0)
    99  	})
   100  
   101  	gtest.PanicStr(`invalid range [1,1)`, func() {
   102  		fun(rndSrc(), 1, 1)
   103  	})
   104  
   105  	gtest.PanicStr(`invalid range [2,1)`, func() {
   106  		fun(rndSrc(), 2, 1)
   107  	})
   108  
   109  	testRandomIntRange[A](0, 1)
   110  	testRandomIntRange[A](0, 2)
   111  	testRandomIntRange[A](0, 3)
   112  	testRandomIntRange[A](0, 16)
   113  	testRandomIntRange[A](32, 48)
   114  
   115  	testRandomIntRanges[A](0, 16)
   116  	testRandomIntRanges[A](32, 48)
   117  }
   118  
   119  func testRandomSintBetween[A gg.Sint]() {
   120  	gtest.PanicStr(`invalid range [1,-1)`, func() {
   121  		gg.RandomIntBetween[A](rndSrc(), 1, -1)
   122  	})
   123  
   124  	gtest.PanicStr(`invalid range [2,-2)`, func() {
   125  		gg.RandomIntBetween[A](rndSrc(), 2, -2)
   126  	})
   127  
   128  	testRandomIntRange[A](-10, 10)
   129  	testRandomIntRanges[A](-10, 10)
   130  }
   131  
   132  func testRandomIntRange[A gg.Int](min, max A) {
   133  	gtest.EqualSet(
   134  		randomIntSlice(128, min, max),
   135  		gg.Range(min, max),
   136  		fmt.Sprintf(`expected range: [%v,%v)`, min, max),
   137  	)
   138  }
   139  
   140  func testRandomIntRanges[A gg.Int](min, max int) {
   141  	for _, max := range gg.Range(min+1, max) {
   142  		for _, min := range gg.Range(min, max) {
   143  			testRandomIntRange(gg.NumConv[A](min), gg.NumConv[A](max))
   144  		}
   145  	}
   146  }
   147  
   148  func randomIntSlice[A gg.Int](count int, min, max A) []A {
   149  	src := rndSrc()
   150  	var set gg.OrdSet[A]
   151  	for range gg.Iter(count) {
   152  		set.Add(gg.RandomIntBetween(src, min, max))
   153  	}
   154  	return set.Slice
   155  }
   156  
   157  func Benchmark_random_int_between_stdlib_true_random(b *testing.B) {
   158  	defer gtest.Catch(b)
   159  	max := new(big.Int).SetUint64(2 << 16)
   160  	b.ResetTimer()
   161  
   162  	for ind := 0; ind < b.N; ind++ {
   163  		gg.Try1(cr.Int(cr.Reader, max))
   164  	}
   165  }
   166  
   167  func Benchmark_random_int_between_stdlib_pseudo_random(b *testing.B) {
   168  	defer gtest.Catch(b)
   169  	src := rndSrc()
   170  	max := new(big.Int).SetUint64(2 << 16)
   171  	b.ResetTimer()
   172  
   173  	for ind := 0; ind < b.N; ind++ {
   174  		gg.Try1(cr.Int(src, max))
   175  	}
   176  }
   177  
   178  func Benchmark_random_int_between_ours_true_random(b *testing.B) {
   179  	defer gtest.Catch(b)
   180  
   181  	for ind := 0; ind < b.N; ind++ {
   182  		gg.RandomIntBetween(cr.Reader, 0, 2<<16)
   183  	}
   184  }
   185  
   186  func Benchmark_random_int_between_ours_pseudo_random(b *testing.B) {
   187  	defer gtest.Catch(b)
   188  	src := rndSrc()
   189  	b.ResetTimer()
   190  
   191  	for ind := 0; ind < b.N; ind++ {
   192  		gg.RandomIntBetween(src, 0, 2<<16)
   193  	}
   194  }
   195  
   196  func TestRandomElem(t *testing.T) {
   197  	defer gtest.Catch(t)
   198  
   199  	gtest.PanicStr(`invalid range [0,0)`, func() {
   200  		gg.RandomElem(rndSrc(), []int{})
   201  	})
   202  
   203  	testRandomElem([]int{10})
   204  	testRandomElem([]int{10, 20})
   205  	testRandomElem([]int{10, 20, 30})
   206  	testRandomElem([]int{10, 20, 30, 40})
   207  	testRandomElem([]int{10, 20, 30, 40, 50})
   208  	testRandomElem([]int{10, 20, 30, 40, 50, 60})
   209  }
   210  
   211  func testRandomElem[A comparable](slice []A) {
   212  	src := rndSrc()
   213  
   214  	var set gg.OrdSet[A]
   215  	for range gg.Iter(64) {
   216  		set.Add(gg.RandomElem(src, slice))
   217  	}
   218  
   219  	gtest.EqualSet(set.Slice, slice)
   220  }