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 }