Say I have a number “85”. I want to count out all the numbers (so no skipping any numbers), but in random order. How would one go into doing that?
local maxNumber = 85;
local TitleBox.Text = "";
Say I have a number “85”. I want to count out all the numbers (so no skipping any numbers), but in random order. How would one go into doing that?
local maxNumber = 85;
local TitleBox.Text = "";
You could create an array with values from 0 to your max number and then choose a random value from that list and remove it.
local maxNumber = 85
local numbers = {}
for i=1, maxNumber do
numbers[i] = i
end
for i=1, maxNumber do
local num
repeat num = math.random(1, maxNumber) until numbers[num]
print(num)
numbers[num] = nil
end
Wouldn’t this be fairly inefficient? You’re essentially looping through random indices of an array until you index an entry which has a non-nil value.
endNum = 85
numbers = {}
for i = 1, endNum do
table.insert(numbers, i)
end
for i = 1, endNum do
local num = math.random(1, #numbers)
print(num)
table.remove(numbers, table.find(numbers, num))
end
This saves a lot on unnecessary operations.
You can go even further by ditching table.find.
endNum = 9
numbers = {}
for i = 1, endNum do
table.insert(numbers, i)
end
for i = 1, endNum do
local num = table.remove(numbers, math.random(1, #numbers))
print(num)
end
endNum = 9
numbers = {}
for i = 1, endNum do
table.insert(numbers, i)
end
for i = 1, endNum do
print(table.remove(numbers, math.random(1, #numbers)))
end
You can go even further by recognizing that table.remove
becomes more inefficient as the maximum number / upper bound of the problem increases. We can instead assign the chosen index via math.random
in the range [currentIndex, maxVal]
with the value associated with the index of the current iteration in the for loop. This ensures that in the next iteration, we choose between a range of indices [currentIndex+1, maxVal]
, excluding already chosen numbers:
local maxVal = 100000 -- change upper bound here
local arr = table.create(maxVal, 0) -- preallocated array
for i = 1, maxVal do
arr[i] = i -- populate array with the desired numbers
end
for currentIndex = 1, maxVal do
local chosenIndex = math.random(currentIndex, maxVal)
local num = arr[chosenIndex] -- your number
print(num)
arr[chosenIndex] = arr[currentIndex]
end
This is just an extra optimization, and for small values this isn’t too impactful.