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.
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.
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)
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
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