rand.odin 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. /*
  2. Package core:math/rand implements various random number generators
  3. */
  4. package rand
  5. import "base:intrinsics"
  6. import "base:runtime"
  7. import "core:math"
  8. import "core:mem"
  9. Generator :: runtime.Random_Generator
  10. Generator_Query_Info :: runtime.Random_Generator_Query_Info
  11. Default_Random_State :: runtime.Default_Random_State
  12. default_random_generator :: runtime.default_random_generator
  13. create :: proc(seed: u64) -> (state: Default_Random_State) {
  14. seed := seed
  15. runtime.default_random_generator(&state)
  16. runtime.default_random_generator_proc(&state, .Reset, ([^]byte)(&seed)[:size_of(seed)])
  17. return
  18. }
  19. /*
  20. Reset the seed used by the context.random_generator.
  21. Inputs:
  22. - seed: The seed value
  23. Example:
  24. import "core:math/rand"
  25. import "core:fmt"
  26. set_global_seed_example :: proc() {
  27. rand.set_global_seed(1)
  28. fmt.println(rand.uint64())
  29. }
  30. Possible Output:
  31. 10
  32. */
  33. @(deprecated="Prefer `rand.reset`")
  34. set_global_seed :: proc(seed: u64) {
  35. runtime.random_generator_reset_u64(context.random_generator, seed)
  36. }
  37. /*
  38. Reset the seed used by the context.random_generator.
  39. Inputs:
  40. - seed: The seed value
  41. Example:
  42. import "core:math/rand"
  43. import "core:fmt"
  44. set_global_seed_example :: proc() {
  45. rand.reset(1)
  46. fmt.println(rand.uint64())
  47. }
  48. Possible Output:
  49. 10
  50. */
  51. reset :: proc(seed: u64, gen := context.random_generator) {
  52. runtime.random_generator_reset_u64(gen, seed)
  53. }
  54. reset_bytes :: proc(bytes: []byte, gen := context.random_generator) {
  55. runtime.random_generator_reset_bytes(gen, bytes)
  56. }
  57. query_info :: proc(gen := context.random_generator) -> Generator_Query_Info {
  58. return runtime.random_generator_query_info(gen)
  59. }
  60. @(private)
  61. _random_u64 :: proc(gen := context.random_generator) -> (res: u64) {
  62. ok := runtime.random_generator_read_ptr(gen, &res, size_of(res))
  63. assert(ok, "uninitialized gen/context.random_generator")
  64. return
  65. }
  66. /*
  67. Generates a random 32 bit value using the provided random number generator. If no generator is provided the global random number generator will be used.
  68. Returns:
  69. - val: A random unsigned 32 bit value
  70. Example:
  71. import "core:math/rand"
  72. import "core:fmt"
  73. uint32_example :: proc() {
  74. fmt.println(rand.uint32())
  75. }
  76. Possible Output:
  77. 10
  78. 389
  79. */
  80. @(require_results)
  81. uint32 :: proc(gen := context.random_generator) -> (val: u32) { return u32(_random_u64(gen)) }
  82. /*
  83. Generates a random 64 bit value using the provided random number generator. If no generator is provided the global random number generator will be used.
  84. Returns:
  85. - val: A random unsigned 64 bit value
  86. Example:
  87. import "core:math/rand"
  88. import "core:fmt"
  89. uint64_example :: proc() {
  90. fmt.println(rand.uint64())
  91. }
  92. Possible Output:
  93. 10
  94. 389
  95. */
  96. @(require_results)
  97. uint64 :: proc(gen := context.random_generator) -> (val: u64) { return _random_u64(gen) }
  98. /*
  99. Generates a random 128 bit value using the provided random number generator. If no generator is provided the global random number generator will be used.
  100. Returns:
  101. - val: A random unsigned 128 bit value
  102. Example:
  103. import "core:math/rand"
  104. import "core:fmt"
  105. uint128_example :: proc() {
  106. fmt.println(rand.uint128())
  107. }
  108. Possible Output:
  109. 10
  110. 389
  111. */
  112. @(require_results)
  113. uint128 :: proc(gen := context.random_generator) -> (val: u128) {
  114. a := u128(_random_u64(gen))
  115. b := u128(_random_u64(gen))
  116. return (a<<64) | b
  117. }
  118. /*
  119. Generates a random 31 bit value using the provided random number generator. If no generator is provided the global random number generator will be used.
  120. The sign bit will always be set to 0, thus all generated numbers will be positive.
  121. Returns:
  122. - val: A random 31 bit value
  123. Example:
  124. import "core:math/rand"
  125. import "core:fmt"
  126. int31_example :: proc() {
  127. fmt.println(rand.int31())
  128. }
  129. Possible Output:
  130. 10
  131. 389
  132. */
  133. @(require_results) int31 :: proc(gen := context.random_generator) -> (val: i32) { return i32(uint32(gen) << 1 >> 1) }
  134. /*
  135. Generates a random 63 bit value using the provided random number generator. If no generator is provided the global random number generator will be used.
  136. The sign bit will always be set to 0, thus all generated numbers will be positive.
  137. Returns:
  138. - val: A random 63 bit value
  139. Example:
  140. import "core:math/rand"
  141. import "core:fmt"
  142. int63_example :: proc() {
  143. fmt.println(rand.int63())
  144. }
  145. Possible Output:
  146. 10
  147. 389
  148. */
  149. @(require_results) int63 :: proc(gen := context.random_generator) -> (val: i64) { return i64(uint64(gen) << 1 >> 1) }
  150. /*
  151. Generates a random 127 bit value using the provided random number generator. If no generator is provided the global random number generator will be used.
  152. The sign bit will always be set to 0, thus all generated numbers will be positive.
  153. Returns:
  154. - val: A random 127 bit value
  155. Example:
  156. import "core:math/rand"
  157. import "core:fmt"
  158. int127_example :: proc() {
  159. fmt.println(rand.int127())
  160. }
  161. Possible Output:
  162. 10
  163. 389
  164. */
  165. @(require_results) int127 :: proc(gen := context.random_generator) -> (val: i128) { return i128(uint128(gen) << 1 >> 1) }
  166. /*
  167. Generates a random 31 bit value in the range `[0, n)` using the provided random number generator. If no generator is provided the global random number generator will be used.
  168. Inputs:
  169. - n: The upper bound of the generated number, this value is exclusive
  170. Returns:
  171. - val: A random 31 bit value in the range `[0, n)`
  172. WARNING: Panics if n is less than 0
  173. Example:
  174. import "core:math/rand"
  175. import "core:fmt"
  176. int31_max_example :: proc() {
  177. fmt.println(rand.int31_max(16))
  178. }
  179. Possible Output:
  180. 6
  181. 500
  182. */
  183. @(require_results)
  184. int31_max :: proc(n: i32, gen := context.random_generator) -> (val: i32) {
  185. if n <= 0 {
  186. panic("Invalid argument to int31_max")
  187. }
  188. if n&(n-1) == 0 {
  189. return int31(gen) & (n-1)
  190. }
  191. max := i32((1<<31) - 1 - (1<<31)%u32(n))
  192. v := int31(gen)
  193. for v > max {
  194. v = int31(gen)
  195. }
  196. return v % n
  197. }
  198. /*
  199. Generates a random 63 bit value in the range `[0, n)` using the provided random number generator. If no generator is provided the global random number generator will be used.
  200. Inputs:
  201. - n: The upper bound of the generated number, this value is exclusive
  202. Returns:
  203. - val: A random 63 bit value in the range `[0, n)`
  204. WARNING: Panics if n is less than 0
  205. Example:
  206. import "core:math/rand"
  207. import "core:fmt"
  208. int63_max_example :: proc() {
  209. fmt.println(rand.int63_max(16))
  210. }
  211. Possible Output:
  212. 6
  213. 500
  214. */
  215. @(require_results)
  216. int63_max :: proc(n: i64, gen := context.random_generator) -> (val: i64) {
  217. if n <= 0 {
  218. panic("Invalid argument to int63_max")
  219. }
  220. if n&(n-1) == 0 {
  221. return int63(gen) & (n-1)
  222. }
  223. max := i64((1<<63) - 1 - (1<<63)%u64(n))
  224. v := int63(gen)
  225. for v > max {
  226. v = int63(gen)
  227. }
  228. return v % n
  229. }
  230. /*
  231. Generates a random 127 bit value in the range `[0, n)` using the provided random number generator. If no generator is provided the global random number generator will be used.
  232. Inputs:
  233. - n: The upper bound of the generated number, this value is exclusive
  234. Returns:
  235. - val: A random 127 bit value in the range `[0, n)`
  236. WARNING: Panics if n is less than 0
  237. Example:
  238. import "core:math/rand"
  239. import "core:fmt"
  240. int127_max_example :: proc() {
  241. fmt.println(rand.int127_max(16))
  242. }
  243. Possible Output:
  244. 6
  245. 500
  246. */
  247. @(require_results)
  248. int127_max :: proc(n: i128, gen := context.random_generator) -> (val: i128) {
  249. if n <= 0 {
  250. panic("Invalid argument to int127_max")
  251. }
  252. if n&(n-1) == 0 {
  253. return int127(gen) & (n-1)
  254. }
  255. max := i128((1<<127) - 1 - (1<<127)%u128(n))
  256. v := int127(gen)
  257. for v > max {
  258. v = int127(gen)
  259. }
  260. return v % n
  261. }
  262. /*
  263. Generates a random integer value in the range `[0, n)` using the provided random number generator. If no generator is provided the global random number generator will be used.
  264. Inputs:
  265. - n: The upper bound of the generated number, this value is exclusive
  266. Returns:
  267. - val: A random integer value in the range `[0, n)`
  268. WARNING: Panics if n is less than 0
  269. Example:
  270. import "core:math/rand"
  271. import "core:fmt"
  272. int_max_example :: proc() {
  273. fmt.println(rand.int_max(16))
  274. }
  275. Possible Output:
  276. 6
  277. 500
  278. */
  279. @(require_results)
  280. int_max :: proc(n: int, gen := context.random_generator) -> (val: int) {
  281. if n <= 0 {
  282. panic("Invalid argument to int_max")
  283. }
  284. when size_of(int) == 4 {
  285. return int(int31_max(i32(n), gen))
  286. } else {
  287. return int(int63_max(i64(n), gen))
  288. }
  289. }
  290. /*
  291. Generates a random double floating point value in the range `[0, 1)` using the provided random number generator. If no generator is provided the global random number generator will be used.
  292. Returns:
  293. - val: A random double floating point value in the range `[0, 1)`
  294. Example:
  295. import "core:math/rand"
  296. import "core:fmt"
  297. float64_example :: proc() {
  298. fmt.println(rand.float64())
  299. }
  300. Possible Output:
  301. 0.043
  302. 0.511
  303. */
  304. @(require_results) float64 :: proc(gen := context.random_generator) -> (val: f64) { return f64(int63_max(1<<53, gen)) / (1 << 53) }
  305. /*
  306. Generates a random single floating point value in the range `[0, 1)` using the provided random number generator. If no generator is provided the global random number generator will be used.
  307. Returns:
  308. - val: A random single floating point value in the range `[0, 1)`
  309. Example:
  310. import "core:math/rand"
  311. import "core:fmt"
  312. float32_example :: proc() {
  313. fmt.println(rand.float32())
  314. }
  315. Possible Output:
  316. 0.043
  317. 0.511
  318. */
  319. @(require_results) float32 :: proc(gen := context.random_generator) -> (val: f32) { return f32(int31_max(1<<24, gen)) / (1 << 24) }
  320. /*
  321. Generates a random double floating point value in the range `[low, high)` using the provided random number generator. If no generator is provided the global random number generator will be used.
  322. WARNING: Panics if `high < low`
  323. Inputs:
  324. - low: The lower bounds of the value, this value is inclusive
  325. - high: The upper bounds of the value, this value is exclusive
  326. Returns:
  327. - val: A random double floating point value in the range [low, high)
  328. Example:
  329. import "core:math/rand"
  330. import "core:fmt"
  331. float64_range_example :: proc() {
  332. fmt.println(rand.float64_range(-10, 300))
  333. }
  334. Possible Output:
  335. 15.312
  336. 673.130
  337. */
  338. @(require_results) float64_range :: proc(low, high: f64, gen := context.random_generator) -> (val: f64) {
  339. assert(low <= high, "low must be lower than or equal to high")
  340. val = (high-low)*float64(gen) + low
  341. if val >= high {
  342. val = max(low, high * (1 - math.F64_EPSILON))
  343. }
  344. return
  345. }
  346. /*
  347. Generates a random single floating point value in the range `[low, high)` using the provided random number generator. If no generator is provided the global random number generator will be used.
  348. Inputs:
  349. - low: The lower bounds of the value, this value is inclusive
  350. - high: The upper bounds of the value, this value is exclusive
  351. Returns:
  352. - val: A random single floating point value in the range [low, high)
  353. WARNING: Panics if `high < low`
  354. Example:
  355. import "core:math/rand"
  356. import "core:fmt"
  357. float32_range_example :: proc() {
  358. fmt.println(rand.float32_range(-10, 300))
  359. }
  360. Possible Output:
  361. 15.312
  362. 673.130
  363. */
  364. @(require_results) float32_range :: proc(low, high: f32, gen := context.random_generator) -> (val: f32) {
  365. assert(low <= high, "low must be lower than or equal to high")
  366. val = (high-low)*float32(gen) + low
  367. if val >= high {
  368. val = max(low, high * (1 - math.F32_EPSILON))
  369. }
  370. return
  371. }
  372. /*
  373. Fills a byte slice with random values using the provided random number generator. If no generator is provided the global random number generator will be used.
  374. Due to floating point precision there is no guarantee if the upper and lower bounds are inclusive/exclusive with the exact floating point value.
  375. Inputs:
  376. - p: The byte slice to fill
  377. Returns:
  378. - n: The number of bytes generated
  379. Example:
  380. import "core:math/rand"
  381. import "core:fmt"
  382. read_example :: proc() {
  383. data: [8]byte
  384. n := rand.read(data[:])
  385. fmt.println(n)
  386. fmt.println(data)
  387. }
  388. Possible Output:
  389. 8
  390. [32, 4, 59, 7, 1, 2, 2, 119]
  391. */
  392. @(require_results)
  393. read :: proc(p: []byte, gen := context.random_generator) -> (n: int) {
  394. pos := i8(0)
  395. val := i64(0)
  396. for n = 0; n < len(p); n += 1 {
  397. if pos == 0 {
  398. val = int63(gen)
  399. pos = 7
  400. }
  401. p[n] = byte(val)
  402. val >>= 8
  403. pos -= 1
  404. }
  405. return
  406. }
  407. /*
  408. Creates a slice of `int` filled with random values using the provided random number generator. If no generator is provided the global random number generator will be used.
  409. *Allocates Using Provided Allocator*
  410. Inputs:
  411. - n: The size of the created slice
  412. - allocator: (default: context.allocator)
  413. Returns:
  414. - res: A slice filled with random values
  415. - err: An allocator error if one occured, `nil` otherwise
  416. Example:
  417. import "core:math/rand"
  418. import "core:mem"
  419. import "core:fmt"
  420. perm_example :: proc() -> (err: mem.Allocator_Error) {
  421. data := rand.perm(4) or_return
  422. fmt.println(data)
  423. defer delete(data, context.allocator)
  424. return
  425. }
  426. Possible Output:
  427. [7201011, 3, 9123, 231131]
  428. [19578, 910081, 131, 7]
  429. */
  430. @(require_results)
  431. perm :: proc(n: int, allocator := context.allocator, gen := context.random_generator) -> (res: []int, err: mem.Allocator_Error) #optional_allocator_error {
  432. m := make([]int, n, allocator) or_return
  433. for i := 0; i < n; i += 1 {
  434. j := int_max(i+1, gen)
  435. m[i] = m[j]
  436. m[j] = i
  437. }
  438. return m, {}
  439. }
  440. /*
  441. Randomizes the ordering of elements for the provided slice. If no generator is provided the global random number generator will be used.
  442. Inputs:
  443. - array: The slice to randomize
  444. Example:
  445. import "core:math/rand"
  446. import "core:fmt"
  447. shuffle_example :: proc() {
  448. data: [4]int = { 1, 2, 3, 4 }
  449. fmt.println(data) // the contents are in order
  450. rand.shuffle(data[:])
  451. fmt.println(data) // the contents have been shuffled
  452. }
  453. Possible Output:
  454. [1, 2, 3, 4]
  455. [2, 4, 3, 1]
  456. */
  457. shuffle :: proc(array: $T/[]$E, gen := context.random_generator) {
  458. n := i64(len(array))
  459. if n < 2 {
  460. return
  461. }
  462. i := n - 1
  463. for ; i > (1<<31 - 2); i -= 1 {
  464. j := int63_max(i + 1, gen)
  465. array[i], array[j] = array[j], array[i]
  466. }
  467. for ; i > 0; i -= 1 {
  468. j := int31_max(i32(i + 1), gen)
  469. array[i], array[j] = array[j], array[i]
  470. }
  471. }
  472. /*
  473. Returns a random element from the provided slice. If no generator is provided the global random number generator will be used.
  474. Inputs:
  475. - array: The slice to choose an element from
  476. Returns:
  477. - res: A random element from `array`
  478. Example:
  479. import "core:math/rand"
  480. import "core:fmt"
  481. choice_example :: proc() {
  482. data: [4]int = { 1, 2, 3, 4 }
  483. fmt.println(rand.choice(data[:]))
  484. fmt.println(rand.choice(data[:]))
  485. fmt.println(rand.choice(data[:]))
  486. fmt.println(rand.choice(data[:]))
  487. }
  488. Possible Output:
  489. 3
  490. 2
  491. 2
  492. 4
  493. */
  494. @(require_results)
  495. choice :: proc(array: $T/[]$E, gen := context.random_generator) -> (res: E) {
  496. n := i64(len(array))
  497. if n < 1 {
  498. return E{}
  499. }
  500. return array[int63_max(n, gen)]
  501. }
  502. @(require_results)
  503. choice_enum :: proc($T: typeid, gen := context.random_generator) -> T where intrinsics.type_is_enum(T) {
  504. when size_of(T) <= 8 && len(T) == cap(T) {
  505. when intrinsics.type_is_unsigned(intrinsics.type_core_type(T)) &&
  506. u64(max(T)) > u64(max(i64)) {
  507. i := uint64(gen) % u64(len(T))
  508. i += u64(min(T))
  509. return T(i)
  510. } else {
  511. i := int63_max(i64(len(T)), gen)
  512. i += i64(min(T))
  513. return T(i)
  514. }
  515. } else {
  516. values := runtime.type_info_base(type_info_of(T)).variant.(runtime.Type_Info_Enum).values
  517. return T(choice(values))
  518. }
  519. }
  520. /*
  521. Returns a random *set* bit from the provided `bit_set`.
  522. Inputs:
  523. - set: The `bit_set` to choose a random set bit from
  524. Returns:
  525. - res: The randomly selected bit, or the zero value if `not_empty` is `false`
  526. - not_empty: Whether the bit_set was not empty and thus `res` is actually a random set bit
  527. Example:
  528. import "core:math/rand"
  529. import "core:fmt"
  530. choice_bit_set_example :: proc() {
  531. Flags :: enum {
  532. A,
  533. B = 10,
  534. C,
  535. }
  536. fmt.println(rand.choice_bit_set(bit_set[Flags]{}))
  537. fmt.println(rand.choice_bit_set(bit_set[Flags]{.B}))
  538. fmt.println(rand.choice_bit_set(bit_set[Flags]{.B, .C}))
  539. fmt.println(rand.choice_bit_set(bit_set[0..<15]{5, 1, 4}))
  540. }
  541. Possible Output:
  542. A false
  543. B true
  544. C true
  545. 5 true
  546. */
  547. @(require_results)
  548. choice_bit_set :: proc(set: $T/bit_set[$E], gen := context.random_generator) -> (res: E, not_empty: bool) {
  549. total_set := card(set)
  550. if total_set == 0 {
  551. return {}, false
  552. }
  553. core_set := transmute(intrinsics.type_bit_set_underlying_type(T))set
  554. for target := int_max(total_set, gen); target > 0; target -= 1 {
  555. core_set &= core_set - 1
  556. }
  557. return E(intrinsics.count_trailing_zeros(core_set)), true
  558. }