How to sort this array this way in python?

114 views Asked by At

You are given an array, for example:

arr = [['AB','KR','EH'],['EE','DD','PS'],['GH','LM','XK']]

array printed by rows

Then, through a function, you have to get this:

sorted array printed by rows

The array must be sorted ascending as a whole and not only by rows. You can not create new arrays for this. You have to do it in place.

I tried to find a way to do this with no new arrays but I could not. This is my code, it certainly sorts the array but creates a new array.

def sortArray(arr): #n : filas,columnas
    sorted_arr = []
    for j in arr:
        sorted_arr.extend(j)

    return sorted(sorted_arr)
4

There are 4 answers

6
Andrej Kesely On

Try:

from itertools import islice

arr = [["AB", "KR", "EH"], ["EE", "DD", "PS"], ["GH", "LM", "XK"]]

i = iter(sorted(v for l in arr for v in l))
for l in arr:
    l[:] = islice(i, 0, len(l))

print(arr)

Prints:

[
  ["AB", "DD", "EE"], 
  ["EH", "GH", "KR"], 
  ["LM", "PS", "XK"]
]
0
Unmitigated On

You can perform a selection sort, using indexes from 0 to N * N - 1 where N is the length of the array (since it's square). The corresponding element in the actual array for each index can be calculated by dividing and taking the remainder.

def sortArray(arr):
    n = len(arr)
    for i in range(n * n):
        m = i
        for j in range(i + 1, n * n):
            if arr[j // n][j % n] < arr[m // n][m % n]:
                m = j
        arr[i // n][i % n], arr[m // n][m % n] = arr[m // n][m % n], arr[i // n][i % n]
3
B Remmelzwaal On

Well, if you can't create a new list and it has to be done in-place, you could always just do an exchange sort:

arr = [['AB','KR','EH'],['EE','DD','PS'],['GH','LM','XK']]

def sortedArray(arr):
    height = len(arr)
    width = len(arr[0])
    for left in range(height*width):
        for right in range(left+1, height*width):
            li, lj = left//height, left%width
            ri, rj = right//height, right%width
            if arr[li][lj] > arr[ri][rj]:
                arr[li][lj], arr[ri][rj] = arr[ri][rj], arr[li][lj]
    
    return arr

print(sortedArray(arr))

Output:

[
 ['AB', 'DD', 'EE'], 
 ['EH', 'GH', 'KR'], 
 ['LM', 'PS', 'XK']
]

Looks messy, feels dumb, but at least it does meet the requirements.

0
Kelly Bundy On

(Result is based on their comments, i.e., not exactly as shown in the incorrect image. And using that they said it's always square.)

Solution 1: Odd insertion sort algorithm

a = [['AB','KR','EH'],['EE','DD','PS'],['GH','LM','XK']]

r = range(len(a))
for i in r:
  for j in r:
    for I in r:
      for J in r:
        if a[i][j] < a[I][J]:
          a[i][j], a[I][J] = a[I][J], a[i][j]

print(a)

Output (Attempt This Online!):

[['AB', 'DD', 'EE'], ['EH', 'GH', 'KR'], ['LM', 'PS', 'XK']]

Solution 2: Ordinary insertion sort

Really ordinary. Just one-dimensional insertion sort. But on an object that translates the indices and gets/sets the values in the two-dimensional original:

def insertionSort(A):
  for i, a in enumerate(A):
    while i and a < A[i-1]:
      A[i] = A[i-1]
      i -= 1
    A[i] = a

def sortArray(A):
  class B:
    def __getitem__(_, i):
      return A[i//n][i%n]
    def __setitem__(_, i, value):
      A[i//n][i%n] = value
  n = len(A)
  insertionSort(B())
  return A

arr = [['AB','KR','EH'],['EE','DD','PS'],['GH','LM','XK']]
print(sortArray(arr))

Try it online!