ENET
|
  |
| Joined: 01 Jan 2010 |
| Total Posts: 4820 |
|
|
| 10 Jan 2012 12:27 AM |
I was bored and figured we could use some discussion. So I made an alphabetical sorter and decided to open-source it. Took about 10 - 20 minutes to make. Post your own sorting algorithms. Largest to shortest number, shortest to largest number, etc...
--Algorithm made up/designed by enet. --Created: Jan 9th, 2011 --Don't steal credit noobs! --------------------Member of Scripter Society ----------------------------------------------
list = {"ENET", "Bronce111","Bronce1000","bronce","bronce2","John","Telamon","Builderman","TaslemGuy","Person299","RandomlyNaming"}; --List to be alphabatized
alpha = 'abcdefghijklmnopqrstuvwxyz0123456789';
function sortA(fakeList) local list = {}; for i = 1,#fakeList do list[i] = fakeList[i]:lower(); end local newList = {}; local longest = getLengthLongestWord(list); local id = 0; while(#list > 0)do --Keep getting shortest word and adding to newlist and removing from current list. wait(); local word = findFirstWord(list); local pos = getWordPosition(list, word); table.remove(list, pos); id = id + 1; newList[id]=fakeList[pos]; table.remove(fakeList, pos); end return newList; end
function getWordPosition(list, word) for i = 1,#list do if(list[i]==word)then return i; end end return -1; end
function findFirstWord(list, pos) local current; local shortest = {}; local length = 0; pos = pos or 1; for a = 1,#alpha do local letter = alpha:sub(a,a); for i = 1,#list do if(list[i]:sub(pos, pos) == letter)then length = length + 1; shortest[length] = list[i]; end end if(#shortest>0)then break; end end current = shortest[1]; while(#shortest>1)do wait(); local ns = {}; local id = 1; for i=1,#shortest do local word = compareWords(current, shortest[i]); if(word == current)then table.remove(shortest, i); break; elseif(word == shortest[i])then local currentT = shortest[i]; table.remove(shortest, getWordPosition(shortest, current)); current = currentT; break; end end end return current; end
function compareWords(wrd1, wrd2) local val1, val2; local length = (#wrd1>#wrd2 and #wrd2) or #wrd1; for i=1,length do val1 = alpha:find(wrd1:sub(i,i)); val2 = alpha:find(wrd2:sub(i,i)); if(val1 ~= val2)then break; end end if(val1 > val2)then return wrd2; elseif(val1 < val2)then return wrd1; else --assume they were equal if(#wrd1 > #wrd2)then --word 2 is shorter return wrd2 elseif(#wrd1 < #wrd2)then --word 1 is shorter return wrd1; else --assume the words are the same word return nil; end end end
function getLengthLongestWord(list) local largest = 0; for i = 1,#list do if(#list[i]>largest)then largest = #list[i]; end end return largest; end
function wordsThatStartWithLetterInPos(letter, pos, list) local id = 0; for i=1,#list do if(list[i]:sub(pos,pos)==letter)then id=id+1; end end return id; end
local newL = sortA(list); for i = 1,#newL do print(newL[i]); end
|
|
|
| Report Abuse |
|
|
ENET
|
  |
| Joined: 01 Jan 2010 |
| Total Posts: 4820 |
|
|
| 10 Jan 2012 12:29 AM |
Please favorite and take :). http://www.roblox.com/EnetSortingAlgorithm-alphabetically-item?id=69758339
If you want the tabbed version(ie neater looking code) get it from the above link. |
|
|
| Report Abuse |
|
|
ENET
|
  |
| Joined: 01 Jan 2010 |
| Total Posts: 4820 |
|
|
| 10 Jan 2012 12:30 AM |
Also if you wish to modify the alphabetical order in which it sorts edit....
alpha = 'abcdefghijklmnopqrstuvwxyz0123456789';
add characters if you wish or what not. A is the same as a. B is the same as b. If you modify please give credit for original sauce. |
|
|
| Report Abuse |
|
|
ENET
|
  |
| Joined: 01 Jan 2010 |
| Total Posts: 4820 |
|
|
| 10 Jan 2012 12:34 AM |
My algorithm explained..
1. Iterate through the alpha string and get all the words in the list with the first found character in the alpha string. So if it iterates through all the words and c is the first letter found, than only get those words that begin with c.
2. Compare all those words to get the shortest one.
3. Remove that word from the list.
4. If list empty goto 5 else goto 1
5. Return the new list. |
|
|
| Report Abuse |
|
|
|
| 10 Jan 2012 12:37 AM |
local tab = {"banana","purple","apple"} table.sort(tab)
:D |
|
|
| Report Abuse |
|
|
ENET
|
  |
| Joined: 01 Jan 2010 |
| Total Posts: 4820 |
|
|
| 10 Jan 2012 12:46 AM |
that just made me somewhat mad.. But mine still has more control... IE You can easily change the way it orders.... numbers first, numbers last, a-z, z-a etc.....
Updated the sauce code below. Now in stead of getting the lowest set EVERY iteration, it gets the lowest set first and works it, than goes to the new lowest set. Speeds it up alot!
--Algorithm made up/designed by enet. --Created: Jan 9th, 2011 --Don't steal credit noobs! --------------------Member of Scripter Society ----------------------------------------------
list = {"ENET", "Bronce111","Bronce1000","bronce","bronce2","John","Telamon","Builderman","TaslemGuy","Person299","RandomlyNaming"}; --List to be alphabatized
alpha = 'abcdefghijklmnopqrstuvwxyz0123456789';
function sortA(fakeList) local list = {}; for i = 1,#fakeList do list[i] = fakeList[i]:lower(); end local newList = {}; local longest = getLengthLongestWord(list); local id = 0; while(#list > 0)do --Keep getting shortest word and adding to newlist and removing from current list. wait(); local set = findFirstWordSet(list); if(set and #set > 0)then local word; while(#set > 0)do wait() word,set = findFirstWordInSet(set); local pos = getWordPosition(list, word); local pos2 = getWordPosition(set, word); table.remove(set, pos2); table.remove(list, pos); id = id + 1; newList[id]=fakeList[pos]; table.remove(fakeList, pos); end end end return newList; end
function getWordPosition(list, word) for i = 1,#list do if(list[i]==word)then return i; end end return -1; end
function findFirstWordSet(list, pos) local shortest = {}; local length = 0; pos = pos or 1; for a = 1,#alpha do local letter = alpha:sub(a,a); for i = 1,#list do if(list[i]:sub(pos, pos) == letter)then length = length + 1; shortest[length] = list[i]; end end if(#shortest>0)then break; end end return shortest; end
function findFirstWordInSet(shortest) local current = shortest[1]; while(#shortest>1)do wait(); local ns = {}; local id = 1; for i=1,#shortest do local word = compareWords(current, shortest[i]); if(word == current)then table.remove(shortest, i); break; elseif(word == shortest[i])then local currentT = shortest[i]; table.remove(shortest, getWordPosition(shortest, current)); current = currentT; break; end end end return current, shortest; end
function compareWords(wrd1, wrd2) local val1, val2; local length = (#wrd1>#wrd2 and #wrd2) or #wrd1; for i=1,length do val1 = alpha:find(wrd1:sub(i,i)); val2 = alpha:find(wrd2:sub(i,i)); if(val1 ~= val2)then break; end end if(val1 > val2)then return wrd2; elseif(val1 < val2)then return wrd1; else --assume they were equal if(#wrd1 > #wrd2)then --word 2 is shorter return wrd2 elseif(#wrd1 < #wrd2)then --word 1 is shorter return wrd1; else --assume the words are the same word return nil; end end end
function getLengthLongestWord(list) local largest = 0; for i = 1,#list do if(#list[i]>largest)then largest = #list[i]; end end return largest; end
function wordsThatStartWithLetterInPos(letter, pos, list) local id = 0; for i=1,#list do if(list[i]:sub(pos,pos)==letter)then id=id+1; end end return id; end
local newL = sortA(list); for i = 1,#newL do print(newL[i]); end
|
|
|
| Report Abuse |
|
|
mario703
|
  |
| Joined: 30 Aug 2008 |
| Total Posts: 4 |
|
|
| 10 Jan 2012 01:27 AM |
Did someone say reverse order?
table.sort(tab,function(a,b) return a > b end) |
|
|
| Report Abuse |
|
|
| |
|
aboy5643
|
  |
| Joined: 08 Oct 2010 |
| Total Posts: 5458 |
|
|
| 10 Jan 2012 03:53 PM |
| #'s should take precedence over letters. |
|
|
| Report Abuse |
|
|
|
| 10 Jan 2012 03:55 PM |
alpha = 'abcdefghijklmnopqrstuvwxyz0123456789'; tab = {watever} table.sort(tab, function(a,b) return alpha:find(a) < alpha:find(b) end)
or something like that
do i win |
|
|
| Report Abuse |
|
|
|
| 10 Jan 2012 03:57 PM |
print("potato" > "tomato") --> false print("plant" < "plane") --> false print("computer" > "book") --> true
You can use the > and the < signs to do the same thing. :) |
|
|
| Report Abuse |
|
|
ENET
|
  |
| Joined: 01 Jan 2010 |
| Total Posts: 4820 |
|
|
| 10 Jan 2012 09:39 PM |
Like earlier, ya'll can't manipulate how it sorts as well as my string does. I like my sorts to be a-z 0-9 You can personally add !@#$%^&*() and what not too :) and of course the space character " " |
|
|
| Report Abuse |
|
|
|
| 10 Jan 2012 11:14 PM |
-- Alphabetical Order local function alphaOrder(x) local y = {} for i, v in pairs(x) do y[i] = v end table.sort(y, function(a, b) if a:lower() < b:lower() then return true elseif a:lower() > b:lower() then return false else for i = 2, #a do if not b:sub(i) then return false end if a:sub(i):lower() < b:sub(i):lower() then return true end end end return false end) return y end
-- Reverse Alphabetical Order local function revAlphaOrder(x) local y = {} for i, v in pairs(x) do y[i] = v end table.sort(y, function(a, b) if a:lower() < b:lower() then return false elseif a:lower() > b:lower() then return true else for i = 2, #a do if not b:sub(i) then return true end if a:sub(i):lower() < b:sub(i):lower() then return false end end end return true end) return y end
-- Numeric Ascending Order local function numAscend(x) local y = {} for i, v in pairs(x) do y[i] = v end table.sort(y) return y end
-- Numeric Descending Order local function numDescend(x) local y = {} for i, v in pairs(x) do y[i] = v end table.sort(y, function(a, b) if a > b then return true else return false end end) return y end
local strings = {"merlin", "Na", "S", "Hydrochloric"} local numbers = {3, 17, 1932, 0, 9}
print(unpack(alphaOrder(strings))) --> Hydrochloric merlin Na S print(unpack(revAlphaOrder(strings))) --> S Na Hydrochloric merlin print(unpack(numAscend(numbers))) --> 0 3 9 17 1932 print(unpack(numDescend(numbers))) --> 1932 17 9 3 0
I win >=D And numbers take precedence over letters. Yay ASCII! |
|
|
| Report Abuse |
|
|
KingBoo
|
  |
| Joined: 16 Jul 2007 |
| Total Posts: 8495 |
|
|
| 11 Jan 2012 12:04 AM |
| y u no bubble sort for numbers. am i the only one that does that? |
|
|
| Report Abuse |
|
|
|
| 11 Jan 2012 12:46 PM |
Pretty cool script.
~~Banana phone~~ |
|
|
| Report Abuse |
|
|
MrHistory
|
  |
| Joined: 30 Aug 2010 |
| Total Posts: 5291 |
|
|
| 11 Jan 2012 03:35 PM |
10-20 mins? Pro.
I tried to make dis but got bored:
en wikipedia org/wiki/Quicksort |
|
|
| Report Abuse |
|
|
|
| 11 Jan 2012 05:25 PM |
"Like earlier, ya'll can't manipulate how it sorts as well as my string does."
Maybe, but at least, it'll be 50x faster than your method.
Operators are always extremly fast. |
|
|
| Report Abuse |
|
|
|
| 11 Jan 2012 05:30 PM |
| Mine is based off of ASCII values >=D |
|
|
| Report Abuse |
|
|
ENET
|
  |
| Joined: 01 Jan 2010 |
| Total Posts: 4820 |
|
|
| 11 Jan 2012 05:40 PM |
| Thanks, mrHistory, but not really. I was extremely bored... It didn't take long cause I already had my flow of code planned out before I got started. |
|
|
| Report Abuse |
|
|
|
| 11 Jan 2012 05:48 PM |
Not to brag, but... Mine took less than 5 minutes, planning and all =P Then again, were you aware that the relational operators returned true if the first string's first character's ascii value was [insert operator type here] the second string's first character's ascii value? |
|
|
| Report Abuse |
|
|
ENET
|
  |
| Joined: 01 Jan 2010 |
| Total Posts: 4820 |
|
|
| 11 Jan 2012 05:52 PM |
| @Merlin, no i didn't know that, and mine still over-rules yours. I can set the exact order in which the letters are given value. |
|
|
| Report Abuse |
|
|
|
| 11 Jan 2012 06:08 PM |
| Then it doesn't sort alphabetically. At least by my alphabet. I don't know the order of yours. |
|
|
| Report Abuse |
|
|
1waffle1
|
  |
| Joined: 16 Oct 2007 |
| Total Posts: 16381 |
|
|
| 11 Jan 2012 06:13 PM |
Why are all of yours so HUGE?
function shared.Organize(t) repeat print(table.concat(t, ", ")) wait(.1) X = 0 for i = 1, #t-1 do local A, B = t[i], t[i+1] for a = 1, math.min(#A,#B) do local x = A:sub(a,a) local y = B:sub(a,a) if string.byte(x) > string.byte(y) then local t1, t2 = t[i], t[i+1] t[i], t[i+1] = t2, t1 X=X+1 break elseif string.byte(x) < string.byte(y) then break end end end until X == 0 return t end
|
|
|
| Report Abuse |
|
|
ENET
|
  |
| Joined: 01 Jan 2010 |
| Total Posts: 4820 |
|
|
| 11 Jan 2012 06:47 PM |
@Merlin, It does. The position of 0-9 and special characters aren't set in stone. So if you want a higher control level you need to be able to set where they belong. |
|
|
| Report Abuse |
|
|
|
| 11 Jan 2012 10:00 PM |
@ENET
I believe the normal alphabet is perfectly fine for everyone here. Why in the world would you want to have "more control"?
Yes, your way gives us more control. It is also 15x slower.
Also, table.sort has a second argument that can be used to specify what order you want. Look at Lua's Reference Manual to know more about it.
It sorts the table for you, but it even lets you specify what order you want. In fact, it lets you specify way more than that. |
|
|
| Report Abuse |
|
|