Py_junior
Py_junior

Reputation: 93

generate non duplicate integers in Lua

I am trying to generate 5 random non duplicate values between 0,500 and assign them to 5 variables using Lua.

So far I have used the following code which unsuccessfully attempts to generate the random numbers and assigns the values. The problem is:

  1. this code is sometime generating the duplicate numbers
  2. the name which I want to look like x-1, x-2 and so on, prints like x-1, x-12.

Can you please help me with this.

Example:

v_Name = "x-"
for i =1, 5 do
  X = math.random (0, 500)
  v_Name = v_Name..(i)
  print (v_Name)
  print (X)
 end 

Upvotes: 0

Views: 2670

Answers (4)

Asanda
Asanda

Reputation: 1

I’m new in Lua Here is my attempt that is giving the solution properly without using the math.random function. Do we really have to use the function by the way

local count = 0
local v_name =“ “

for count = 1, 10 do
    v_name = v_name.. “x- “ .. count..” “
end
print (v_name)

Upvotes: 0

Mike V.
Mike V.

Reputation: 2215

Here is a solution, clarified in the comments:

math.randomseed( os.time() ) -- first, sets a seed for the pseudo-random generator

local  function my_random (t,from, to)  -- second, exclude duplicates
   local num = math.random (from, to)
   if t[num] then  num = my_random (t, from, to)   end
   t[num]=num 
   return num
end

local t = {}    -- initialize  table with not duplicate values
local v_Name = "x-"
for i =1, 5 do
  X = my_random (t, 0, 500)
  v_Name = v_Name .. i    -- It is better to use the table here and concatenate it after..
  print (v_Name, "=" ,X)
 end 

Upvotes: 4

James Penner
James Penner

Reputation: 81

If you're looking for a simple answer without metatables..

local result = {}
local rand_num = {}
local v_Name = "x-"

for i=1, 500, 1 do
table.insert(rand_num, i)
end

for i=1, 5, 1 do
local r = math.random(1, #rand_num)
table.insert(result, rand_num[r])
table.remove(rand_num, r)
end

for i,v in pairs(result) do
print(v_Name .. v)
end

Upvotes: 0

siffiejoe
siffiejoe

Reputation: 4271

The usual approach for this sort of thing is to do a random shuffle of an array containing all your possible random numbers and take the first n of those. As an optimization you can only shuffle the first n elements you need.

local meta = {
  __index = function( _, i ) return i end
}

local function random_n( n, i, j )
  local result = {}
  local temp = setmetatable( {}, meta )
  for k = 1, n do
    -- swap first element in range with randomly selected element in range
    local idx = math.random( i, j )
    local v = temp[ idx ]
    temp[ idx ] = temp[ i ]
    result[ k ] = v
    i = i + 1 -- first element in range is fixed from now on
  end
  return result
end

math.randomseed( os.time() )

local t = random_n( 5, 0, 500 )
for i,v in ipairs( t ) do
  print( i, v )
end

Upvotes: 1

Related Questions