0

I need this for a game server using Lua..

I would like to be able to save all combinations of a name into a string that can then be used with:

if exists (string)

example:

ABC_-123    
aBC_-123     
AbC_-123 
ABc_-123     
abC_-123

etc

in the game only numbers, letters and _ - . can be used as names.

(A_B-C, A-B.C, AB_8 ... etc)

I understand the logic I just don't know how to code it:D

0-Lower    
1-Upper

then

000    
001

etc

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
sarin
  • 3
  • 1
  • 1
    Do you really need to generate all such combinations, or do you just want to check whether a new string is present in all such combinations of another string? These are two different tasks with different solutions. – dlask Nov 01 '15 at 15:58
  • all combinations yeah – sarin Nov 01 '15 at 16:04
  • 1
    If you want to use it like `if exists (string)`, if I understand it correctly, you don't need all combinations. So which exactly is expected? – Yu Hao Nov 01 '15 at 16:18
  • maybe i shouldnt have added the if exits comment, maybe its confusing...its hard to explain. "if mapingamefolder exists" is a function in that games mod. – sarin Nov 01 '15 at 16:35
  • Are you looking for a specific directory in case-insensitive way on a case-sensitive file system? – dlask Nov 01 '15 at 17:00

3 Answers3

1

You can use recursive generator. The first parameter contains left part of the string generated so far, and the second parameter is the remaining right part of the original string.

function combinations(s1, s2)
        if s2:len() > 0 then
                local c = s2:sub(1, 1)
                local l = c:lower()
                local u = c:upper()
                if l == u then
                        combinations(s1 .. c, s2:sub(2))
                else
                        combinations(s1 .. l, s2:sub(2))
                        combinations(s1 .. u, s2:sub(2))
                end
        else
                print(s1)
        end
end

So the function is called in this way.

combinations("", "ABC_-123")

You only have to store intermediate results instead of printing them.

dlask
  • 8,776
  • 1
  • 26
  • 30
  • That works :D Thx a lot. Now i only hope it wont lag too much in game. – sarin Nov 01 '15 at 16:55
  • Ok ill try to write in more detail but its too complicated for my brain:D So you have this game that has an unofficial server LUA mod. I added a racing timer to the server, people can send maps and so on and records are stored for each map now problem i get is that i can A block people from uploading maps or B somehow make it so that all maps that are sent to the server are treated as case-insensitive. There is only a linux version of the server so if the server has a map named RACE1 some player can send a map named rACE1 which will then share a score or be 2 separate maps which is not good. – sarin Nov 01 '15 at 17:06
  • What about storing these files with *normalized* names, e.g. in lowercase? – dlask Nov 01 '15 at 17:10
  • server doesnt allow me to act before the map is sent or to change its name:( Also problem is that users know the maps and their cases well and are also using auto completion when voting them example: MAp+tab will find the MAp01 on their system and vote it as that. – sarin Nov 01 '15 at 17:15
  • @sarin it's Lua, not LUA, Lua is not an acronym. – warspyking Nov 01 '15 at 21:11
0

If you are interested only in the exists function then you don't need all combinations.

local stored_string = "ABC_-123"

function exists(tested_string)
        return stored_string:lower() == tested_string:lower()
end

You simply compare the stored string and the tested string in case-insensitive way.

It can be easily tested:

assert(exists("abC_-123"))
assert(not exists("abd_-123"))
dlask
  • 8,776
  • 1
  • 26
  • 30
  • thx, but it really needs to be something like this: http://stackoverflow.com/questions/11144389/find-all-upper-lower-and-mixed-case-combinations-of-a-string while normally passing the numbers and special characters or this http://unix.stackexchange.com/questions/168181/get-all-possible-combinations-of-a-word-in-lower-uppercase-letters – sarin Nov 01 '15 at 16:43
0

How to do this?

There's native function in Lua to generate all permutations of a string, but here are a few things that may prove useful.


Substrings

Probably the simplest solution, but also the least flexible. Rather than combinations, you can check if a substring exists within a given string.

if str:find(substr) then
    --code
end

If this solves your problem, I highly reccomend it.


Get all permutations

A more expensive, but still a working solution. This accomplishes nearly exactly what you asked.

function GetScrambles(str, tab2)
   local tab = {}
   for i = 1,#str do
      table.insert(tab, str:sub(i, i))
   end
   local tab2 = tab2 or {}
   local scrambles = {}
   for i = 0, Count(tab)-1 do
      local permutation = ""
      local a = Count(tab)
      for j = 1, #tab do
         tab2[j] = tab[j]
      end

      for j = #tab, 1, -1 do
         a = a / j
         b = math.floor((i/a)%j) + 1
         permutation = permutation .. tab2[b]
         tab2[b] = tab2[j]
      end
      table.insert(scrambles, permutation)
   end
   return scrambles
end

What you asked

Basically this would be exactly what you originally asked for. It's the same as the above code, except with every substring of the string.

function GetAllSubstrings(str)
    local substrings = {}
    for i = 1,#str do
        for ii = i,#str do
            substrings[#substrings+1]=str:sub(ii)
        end
    end
    return substrings
end

Capitals

You'd basically have to, with every permutation, make every possible combination of capitals with it.

This shouldn't be too difficult, I'm sure you can code it :)


Are you joking?

After this you should probably be wondering. Is all of this really necessary? It seems like a bit much!

The answer to this lies in what you are doing. Do you really need all the combinations of the given characters? I don't think so. You say you need it for case insensitivity in the comments... But did you know you could simply convert it into lower/upper case? It's very simple

local str = "hELlO"
print(str:lower())
print(str:upper())

This is HOW you should store names, otherwise you should leave it case sensitive.


You decide

Now YOU pick what you're going to do. Whichever direction you pick, I wish you the best of luck!

warspyking
  • 3,045
  • 4
  • 20
  • 37