Here is an algorithm in O(ns)
where n is the length of the array and s the maximum length of the strings. It uses the trie method. Instead of padding with spaces or zeros, it pads with fake numbers.
If the numbers 544, 54 are present in a group then 54 is equivalent to 545, and should go in front (we pad 54 with a fake 5 in its last digit).
To compare [5, 554, 45],
- first round (most significant digit), splits it into [5, 554], [45]
- second round [5, 554], [45]
- third round [5], [554], [45] (because 5 are padded with fake 5s)
def pad_with_fake(L):
outL = []
for x in L:
while len(str(x)) < maxlen:
lead = x[0]
if lead not in fake_digits:
x = x + fake_digits[int(lead)]
else:
x = x + lead
outL.append(x)
return outL
def arrange_number_at_digit_position(pos,inL):
outL = []
for digit in digits:
subL = []
for x in inL:
if str(x)[pos] == digit:
subL.append(x)
if subL != []:
outL.append(subL)
return outL
def arrange(inL):
maxlen = max([len(l) for l in inL])
i = 0
outLs = [[inL]]
while i < maxlen:
outL = []
for l in outLs[i]:
outL = outL + (arrange_number_at_digit_position(i,l))
outLs = outLs + [outL]
i = i+1
return outLs
def main():
inL = [559, 5, 55, 59, 549, 544, 54]
L = [str(l) for l in inL]
digits = [0,1,2,3,4,5,6,7,8,9]
fake_digits = ['a','b','c','d','e','f','g','h','i','j']
digits = ['9','j','8','i','7','h','6','g','5','f','4','e','3','d','2','c','1','b','a','0']
L = pad_with_fake(L)
outLs = arrange(L)
for l in outLs:
print(l)
final_string = ""
for l in outLs[-1]:
final_string = final_string + "|" + l[0]
for i in range(0,10):
final_string = final_string.replace(fake_digits[i],"")
print("input", inL, "--> output", final_string)
main()
Example
[['559', '5ff', '55f', '59f', '549', '544', '54f']]
[['559', '5ff', '55f', '59f', '549', '544', '54f']]
[['59f'], ['559', '55f'], ['5ff'], ['549', '544', '54f']]
[['59f'], ['559'], ['55f'], ['5ff'], ['549'], ['54f'], ['544']]
input [559, 5, 55, 59, 549, 544, 54] --> output |59|559|55|5|549|54|544