Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How do I make a random number sequence?

Asked by
SuperFryX 130
9 years ago

How do I make a random number sequence? Not something like (1,2,2,4) I need it to only use each number once. For my script there will be 4 intergers, so a random sequence would look something like (3,1,2,4) I have no idea how to do this and thought you guys could help.

1 answer

Log in to vote
1
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
9 years ago

There are essentially 3 ways to think about this problem to solve it.

Shuffling is the briefest and fastest to run, but slightly harder to reason about than keeping track of which ones have not been used.

Shuffling

You can think about it as shuffling {1, 2, 3, 4}. This is the most efficient way to do it, though it's slightly tricky to do right. The simplest (correct) shuffling algorithm is the Fisher-Yates shuffle. It looks like this:

local n = 4

list = {}
for i = 1, n do
    list[i] = i
end -- build the list

-- N time: as fast as possible!

-- Shuffle:
for i = n, 1, -1 do
    local j = math.random(i)
    list[i], list[j] = list[j], list[i]
end

print( unpack(list) )
-- 4 1 3 2
-- (answers will vary)

Pick a number that hasn't been used yet

You can accomplish this in a few ways. One way (bad) is to keep trying random numbers until you get one that's new: Warning: Incredibly slow.

local n = 4

-- WARNING: VERY SLOW
local used = {} -- which numbers have been used?
local list = {}
while #list < n do
    local try = math.random(n)
    if not used[try] then
        used[try] = true
        table.insert(list, try)
    end
end

A better way is to keep track of a list of numbers you haven't used, and remove from that list; this prevents you from wasting time repeatedly picking numbers you've seen before (much faster; still slower than shuffling):

local n = 4

-- N^2 time
local unused = {}
for i = 1, n do
    unused[i] = i
end

while #list < n do
    local choice = table.remove(unused, math.random(#unused))
    table.insert(list, choice)
end

Rank the results in a really-random list

If you had something like {0.23, 0.83, 0.11, .74}, you could write down the rank of each of the random numbers as {2, 4, 1, 3}. This is a valid way to get random numbers, but is sort of messy and is much slower than shuffling.

local n = 4

-- N^2 time
local seed = {}
for i = 1, n do
    seed[i] = math.random()
end

local list = {}
for i = 1, n do
    local less = 0
    for j = 1, n do
        if seed[j] == seed[i] then
            if i < j then
                less = less + 1
            end
        elseif seed[j] < seed[i] then
            less = less + 1
        end
    end
    list[i] = less + 1
end
Ad

Answer this question