Repository: JuliaLang/julia
File: stdlib/Random/src/misc.jl (Julia)

Code before:
julia> randstring(Xoshiro(3), 'a':'z', 6)
"iyzcsm"

julia> randstring("ACGT")
"TGCTCCTC"
```

!!! note
    `chars` can be any collection of characters, of type `Char` or
    `UInt8` (more efficient), provided [`rand`](@ref) can randomly
    pick characters from it.
"""
function randstring end

let b = UInt8['0':'9';'A':'Z';'a':'z']
    global randstring

    function randstring(r::AbstractRNG, chars=b, n::Integer=8)
        _n = convert(Int, n)
        T = eltype(chars)
        if T === UInt8
            str = Base._string_n(_n)
            GC.@preserve str rand!(r, UnsafeView(pointer(str), _n), chars)
            return str
        else
            v = Vector{T}(undef, _n)
            rand!(r, v, chars)
            return String(v)
        end
    end

    randstring(r::AbstractRNG, n::Integer) = randstring(r, b, n)
    randstring(chars=b, n::Integer=8) = randstring(default_rng(), chars, n)
    randstring(n::Integer) = randstring(default_rng(), b, n)
end


## randsubseq & randsubseq!

# Fill S (resized as needed) with a random subsequence of A, where
# each element of A is included in S with independent probability p.
# (Note that this is different from the problem of finding a random
#  size-m subset of A where m is fixed!)
function randsubseq!(r::AbstractRNG, S::AbstractArray, A::AbstractArray, p::Real)
    require_one_based_indexing(S, A)
    0 <= p <= 1 || throw(ArgumentError("probability $p not in [0,1]"))
    n = length(A)
    p == 1 && return copyto!(resize!(S, n), A)
    empty!(S)
    p == 0 && return S
    nexpected = p * length(A)

Review comment (suggestion):
```suggestion
            v = Vector{T}(undef, n)
```

Code after:
julia> randstring(Xoshiro(3), 'a':'z', 6)
"iyzcsm"

julia> randstring("ACGT")
"TGCTCCTC"
```

!!! note
    `chars` can be any collection of characters, of type `Char` or
    `UInt8` (more efficient), provided [`rand`](@ref) can randomly
    pick characters from it.
"""
function randstring end

let b = UInt8['0':'9';'A':'Z';'a':'z']
    global randstring

    function randstring(r::AbstractRNG, chars, n::Int)
        T = eltype(chars)
        if T === UInt8
            str = Base._string_n(n)
            GC.@preserve str rand!(r, UnsafeView(pointer(str), n), chars)
            return str
        else
            v = Vector{T}(undef, n)
            rand!(r, v, chars)
            return String(v)
        end
    end

    # Zero-arg methods:
    randstring() = randstring(default_rng(), b, 8)
    # One-arg methods:
    randstring(r::AbstractRNG) = randstring(r, b, 8)
    randstring(chars) = randstring(default_rng(), chars, 8)
    randstring(n::Integer) = randstring(default_rng(), b, convert(Int, n))
    # Two-arg methods:
    randstring(r::AbstractRNG, chars) = randstring(r, chars, 8)
    randstring(r::AbstractRNG, n::Integer) = randstring(r, b, convert(Int, n))
    randstring(chars, n::Integer) = randstring(default_rng(), chars, convert(Int, n))
    # Three-arg methods:
    randstring(r::AbstractRNG, chars, n::Integer) = randstring(r, chars, convert(Int, n))
end


## randsubseq & randsubseq!

# Fill S (resized as needed) with a random subsequence of A, where
# each element of A is included in S with independent probability p.
# (Note that this is different from the problem of finding a random
#  size-m subset of A where m is fixed!)