1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

rand: move functions from rand.util to the main module (#13840)

This commit is contained in:
Subhomoy Haldar
2022-03-27 20:08:59 +05:30
committed by GitHub
parent 875ad1f6ea
commit f75ce9dd82
5 changed files with 142 additions and 131 deletions

View File

@ -274,6 +274,76 @@ pub fn (mut rng PRNG) ascii(len int) string {
return internal_string_from_set(mut rng, rand.ascii_chars, len)
}
// Configuration struct for the shuffle functions.
// The start index is inclusive and the end index is exclusive.
// Set the end to 0 to shuffle until the end of the array.
[params]
pub struct ShuffleConfigStruct {
pub:
start int
end int
}
fn (config ShuffleConfigStruct) validate_for<T>(a []T) ? {
if config.start < 0 || config.start >= a.len {
return error("argument 'config.start' must be in range [0, a.len)")
}
if config.end < 0 || config.end > a.len {
return error("argument 'config.end' must be in range [0, a.len]")
}
}
// shuffle randomly permutates the elements in `a`. The range for shuffling is
// optional and the entire array is shuffled by default. Leave the end as 0 to
// shuffle all elements until the end.
[direct_array_access]
pub fn (mut rng PRNG) shuffle<T>(mut a []T, config ShuffleConfigStruct) ? {
config.validate_for(a) ?
new_end := if config.end == 0 { a.len } else { config.end }
for i in config.start .. new_end {
x := rng.int_in_range(i, new_end) or { config.start }
// swap
a_i := a[i]
a[i] = a[x]
a[x] = a_i
}
}
// shuffle_clone returns a random permutation of the elements in `a`.
// The permutation is done on a fresh clone of `a`, so `a` remains unchanged.
pub fn (mut rng PRNG) shuffle_clone<T>(a []T, config ShuffleConfigStruct) ?[]T {
mut res := a.clone()
rng.shuffle(mut res, config) ?
return res
}
// choose samples k elements from the array without replacement.
// This means the indices cannot repeat and it restricts the sample size to be less than or equal to the size of the given array.
// Note that if the array has repeating elements, then the sample may have repeats as well.
pub fn (mut rng PRNG) choose<T>(array []T, k int) ?[]T {
n := array.len
if k > n {
return error('Cannot choose $k elements without replacement from a $n-element array.')
}
mut results := []T{len: k}
mut indices := []int{len: n, init: it}
rng.shuffle(mut indices) ?
for i in 0 .. k {
results[i] = array[indices[i]]
}
return results
}
// sample samples k elements from the array with replacement.
// This means the elements can repeat and the size of the sample may exceed the size of the array.
pub fn (mut rng PRNG) sample<T>(array []T, k int) []T {
mut results := []T{len: k}
for i in 0 .. k {
results[i] = array[rng.intn(array.len) or { 0 }]
}
return results
}
__global default_rng &PRNG
// new_default returns a new instance of the default RNG. If the seed is not provided, the current time will be used to seed the instance.
@ -440,17 +510,17 @@ const (
// users or business transactions.
// (https://news.ycombinator.com/item?id=14526173)
pub fn ulid() string {
return internal_ulid_at_millisecond(mut default_rng, u64(time.utc().unix_time_milli()))
return default_rng.ulid()
}
// ulid_at_millisecond does the same as `ulid` but takes a custom Unix millisecond timestamp via `unix_time_milli`.
pub fn ulid_at_millisecond(unix_time_milli u64) string {
return internal_ulid_at_millisecond(mut default_rng, unix_time_milli)
return default_rng.ulid_at_millisecond(unix_time_milli)
}
// string_from_set returns a string of length `len` containing random characters sampled from the given `charset`
pub fn string_from_set(charset string, len int) string {
return internal_string_from_set(mut default_rng, charset, len)
return default_rng.string_from_set(charset, len)
}
// string returns a string of length `len` containing random characters in range `[a-zA-Z]`.
@ -468,19 +538,28 @@ pub fn ascii(len int) string {
return string_from_set(rand.ascii_chars, len)
}
// shuffle randomly permutates the elements in `a`.
pub fn shuffle<T>(mut a []T) {
len := a.len
for i in 0 .. len {
si := i + intn(len - i) or { len }
a[si], a[i] = a[i], a[si]
}
// shuffle randomly permutates the elements in `a`. The range for shuffling is
// optional and the entire array is shuffled by default. Leave the end as 0 to
// shuffle all elements until the end.
pub fn shuffle<T>(mut a []T, config ShuffleConfigStruct) ? {
default_rng.shuffle(mut a, config) ?
}
// shuffle_clone returns a random permutation of the elements in `a`.
// The permutation is done on a fresh clone of `a`, so `a` remains unchanged.
pub fn shuffle_clone<T>(a []T) []T {
mut res := a.clone()
shuffle(mut res)
return res
pub fn shuffle_clone<T>(a []T, config ShuffleConfigStruct) ?[]T {
return default_rng.shuffle_clone(a, config)
}
// choose samples k elements from the array without replacement.
// This means the indices cannot repeat and it restricts the sample size to be less than or equal to the size of the given array.
// Note that if the array has repeating elements, then the sample may have repeats as well.
pub fn choose<T>(array []T, k int) ?[]T {
return default_rng.choose(array, k)
}
// sample samples k elements from the array with replacement.
// This means the elements can repeat and the size of the sample may exceed the size of the array.
pub fn sample<T>(array []T, k int) []T {
return default_rng.sample(array, k)
}