Блокування сортування рядків та стовпців у двовимірному масиві


15

Давши 2D масив цілих чисел, давайте сортуватимемо його рядки та стовпці по блоках. Це означає, що вам потрібно лише сортувати заданий рядок або стовпець, але застосувати перетворення, необхідні для їх сортування, до всіх інших рядків або стовпців у двовимірному масиві.

Правила

  • Введеним буде 2D масив цілих чисел та 1-індексоване ціле число. Це ціле число буде представляти рядок, який буде відсортовано, якщо число додатне, або стовпець, який буде відсортований, якщо число від’ємне (або навпаки, який ви хочете). Приклад: Давши 4x3масив (рядки x стовпці), ви можете сортувати другий стовпець із -2аргументом або третій рядок з 3аргументом. Цей другий аргумент ніколи не буде дорівнює нулю, і його абсолютне значення ніколи не буде більше відповідного розміру масиву.
  • Виведенням також буде двовимірний масив цілих чисел із необхідними перетвореннями, застосованими для сортування заданого рядка чи стовпця. Крім того, ви можете просто записати масив в STDOUT.
  • Вихідний масив матиме вказаний рядок або стовпець, відсортований у порядку зростання. Просто зауважте, що коли вам потрібно поміняти місцями два числа, цілі стовпці, у яких лежать числа, будуть замінені. І коли вам потрібно поміняти місцями два числа в стовпчик, ці рядки, в яких лежать числа, будуть замінені.
  • У випадку, коли одне і те ж число відображається кілька разів у рядку / стовпці для сортування, можливе декілька рішень відповідно до способу заміни значень, просто виконайте це відповідно до решти рядків / стовпців, які потрібно замінити.

Приклади

Positive indices for rows and negative indices for columns

[5  8  7  6                                  [1  3  2  4
 1  3  2  4   order by -3 (3rd column)  -->   9  6  3  0
 9  6  3  0]                                  5  8  7  6]

[5  8  7  6                                  [9  6  3  0
 1  3  2  4   order by -4 (4th column)  -->   1  3  2  4
 9  6  3  0]                                  5  8  7  6]

[5  8  7  6                                  [5  7  8  6
 1  3  2  4     order by 2 (2nd row)  -->     1  2  3  4
 9  6  3  0]                                  9  3  6  0]

[5  8  7  6                                  [6  7  8  5
 1  3  2  4     order by 3 (3rd row)  -->     4  2  3  1
 9  6  3  0]                                  0  3  6  9]

[1  2                                    [1  2     [3  2
 3  2]   order by -2 (2nd column)  -->    3  2] or  1  2]  (both are valid)

[7  5  9  7                                  [5  7  7  9     [5  7  7  9
 1  3  2  4     order by 1 (1st row)  -->     3  1  4  2  or  3  4  1  2
 9  6  3  0]                                  6  9  0  3]     6  0  9  3]

Це , тому може виграти найкоротший код для кожної мови!


Це відбувається з пісочниці .
Чарлі

Чи можемо ми змінити ціле подання? мінус для рядків і позитивний для стовпців?
Luis felipe De jesus Munoz

1
@LuisfelipeDejesusMunoz так, про це йдеться у запитанні.
Чарлі

Чи може рядок / стовпець містити повторювані числа?
Кевін Кройссен

@KevinCruijssen так, дивіться останні приклади та останній пункт правил.
Чарлі

Відповіді:


7

R , 55 байт

function(x,n)`if`(n>0,x[,+x[n,]],x[+x[,-n],])
`+`=order

Спробуйте в Інтернеті!

Переназначає +оператора (фактично функцію в R) до orderфункції, яка повертає показники вектора від найменшого до найбільшого. Тоді це просто маніпуляція масивом.





4

Japt , 18 17 байт

мінус для рядків і позитивний для стовпців

>0?VñgUÉ:ßUa Vy)y

Спробуйте в Інтернеті!


Це не вдається, коли Uнегативно - проте попередня 17-байтна версія працює.
Кудлатий

@Shaggy Моє погано, я хоч і працював би так чи інакше, зовсім не перевіряв
Luis felipe De jesus Munoz

Непогана ідея, однак передача функції в якості першого аргументу ßавтоматично застосовується до цього U. Це може створити проблеми із спробою передачі буквальних рядків, але все-таки опублікувати пропозицію репортажу GitHub для подальшого дослідження.
Кудлатий

4

05AB1E , 25 24 14 байт

diø}Σ¹Ä<è}¹diø

Цілих -10 байт завдяки @Emigna .

Використовує позитивне ціле введення для сортування рядків, мінус для стовпців.

Спробуйте в Інтернеті або перевірте всі тестові випадки .

Пояснення:

di }      # If the (implicit) integer input is positive:
  ø       #  Swap the rows and columns of the (implicit) matrix input
          #   i.e. 3 and [[5,8,7,6],[1,3,2,4],[9,6,3,0]]
          #    → [[5,1,9],[8,3,6],[7,2,3],[6,4,0]]
Σ    }    # Sort the rows of this matrix by:
 ¹Ä       #  Take the absolute value of the input
          #   i.e. -3 → 3
   <      #  Decreased by 1 to make it 0-indexed
          #   i.e. 3 → 2
    è     #  And index it into the current row
          #   i.e. [5,8,7,6] and 2 → 7
          #   i.e. [5,1,9] and 2 → 9
          #  i.e. [[5,1,9],[8,3,6],[7,2,3],[6,4,0]] sorted by [9,6,3,0]
          #   → [[6,4,0],[7,2,3],[8,3,6],[5,1,9]]
          #  i.e. [[5,8,7,6],[1,3,2,4],[9,6,3,0]] sorted by [7,2,3]
          #   → [[1,3,2,4],[9,6,3,0],[5,8,7,6]]
¹di       # And if the integer input was positive:
   ø      #  Swap the rows and columns back again now that we've sorted them
          #   i.e. 3 and [[6,4,0],[7,2,3],[8,3,6],[5,1,9]]
          #    → [[6,7,8,5],[4,2,3,1],[0,3,6,9]]
          # (And implicitly output the now sorted matrix)

1
Я отримав diø}Σ¹Ä<è]¹diøваш підмножина, тому окремої відповіді я не публікую.
Емінья

@Emigna Dang, ти робиш це так просто. Тепер, коли я бачу це, я не можу повірити, що я сам про це не думав, але в той же час геніальний. Дякую! Завдяки вам збереглися колосальні 10 байт.
Кевін Кройсейсен

4

JavaScript (ES6), 90 байт

t=m=>m[0].map((_,x)=>m.map(r=>r[x]))
f=(m,k)=>k<0?m.sort((a,b)=>a[~k]-b[~k]):t(f(t(m),-k))

Спробуйте в Інтернеті!

Як?

JS не має власного способу транспозиції, тому нам потрібно визначити один:

t = m =>              // given a matrix m[]
  m[0].map((_, x) =>  // for each column at position x in m[]:
    m.map(r =>        //   for each row r in m[]:
      r[x]            //     map this cell to r[x]
    )                 //   end of map() over rows
  )                   // end of map() over columns

Основна функція:

f = (m, k) =>         // given a matrix m[] and an integer k
  k < 0 ?             // if k is negative:
    m.sort((a, b) =>  //   given a pair (a, b) of matrix rows, sort them:
      a[~k] - b[~k]   //     by comparing a[-k - 1] with b[-k - 1]
    )                 //   end of sort
  :                   // else:
    t(f(t(m), -k))    //   transpose m, call f() with -k and transpose the result

k=2

M=(587613249630)t(M)=(519836723640)f(t(M),2)=(519723836640)f(M,2)=t(f(t(M),2))=(578612349360)

3

MATL , 17 байт

y0>XH?!]w|2$XSH?!

Спробуйте в Інтернеті!

Або перевірити всі тестові випадки

Пояснення

y       % Implicit inputs: number n, matrix M. Duplicate from below: pushes n, M, n
0>      % Greater than 0?
XH      % Copy into clipboard H
?       % If true
  !     %   Transpose matrix. This way, when we sort the rows it will correspond
        %   to sorting the columns of the original M
]       % End
w       % Swap: moves n to top
|       % Absolute value
2$XS    % Two-input sortrows function: sorts rows by specified column
H       % Push contents from clipboard H
?       % If true
  !     %   Transpose again, to convert rows back to columns
        % Implicit end
        % Implicit display


2

Python 2 , 71 70 байт

f=lambda m,n:n<0and sorted(m,key=lambda l:l[~n])or zip(*f(zip(*m),-n))

Спробуйте в Інтернеті!


Якщо nвід’ємник, рядки сортуються на основі стовпцяn .

В іншому випадку матриця транспонується, сортується таким же чином і знову переміщується назад.



1

C # (.NET Core) , 186 байт

(x,y)=>{Func<int[][],int[][]>shift=a=> a[0].Select((r,i)=>a.Select(c=>c[i]).ToArray()).ToArray();return y>0?shift(shift(x).OrderBy(e=>e[y-1]).ToArray()):x.OrderBy(e=>e[-y-1]).ToArray();}

Спробуйте в Інтернеті!

Безголівки:

    private static int[][] Blocksort0a(int[][] array, int sortingInstruction)
    {
        Func<int[][], int[][]> shift = a => a[0].Select((r, i) => a.Select(c => c[i]).ToArray()).ToArray();

        sortingInstruction++;

        array = sortingInstruction < 0 ? 
        shift(shift(array).OrderBy(e => e[-sortingInstruction]).ToArray()) 
             : 
        array.OrderBy(e => e[sortingInstruction]).ToArray();

        return null;
    }

Функцію shift ми будемо використовувати двічі, тому змінна функції заощадить простір. Функція повторюється через горизонтальний розмір масиву в індексі і додає кожен елемент цього індексу в кожному горизонтальному масиві до нового вихідного масиву (по горизонталі) - приблизно такий самий, як у рішенні JS Arnoud.

Тепер упорядкування просте, впорядкуйте горизонтальний масив за номером-в-індексі (аргумент -1), необов'язково зміщуючи масив до і після сортування.

Якщо бачити, як конкретно йдеться про масив, ми перетворюємося на масив кілька разів (дуже, дуже марно). Відчуття трохи дурного використання такої багатослівної мови в коді гольф-хе-хе.


1

C # (.NET Core) , 142/139 138/135 байт (і ще один -1 Кевін)

(a,s)=>s<0?a.OrderBy(e=>e[~s]).ToArray():a.Select(f=>a[s-1].Select((v,j)=>new{v,j}).OrderBy(e=>e.v).Select(e=>f[e.j]).ToArray()).ToArray()

Спробуйте в Інтернеті!

Безголівки:

    private static int[][] Blocksort0b(int[][] array, int sortingInstruction)
    {
        if (sortingInstruction < 0) { return array.OrderBy(e => e[-sortingInstruction - 1]).ToArray(); }
        var rowIndices = array[sortingInstruction - 1].Select((value, index) => (value, index)).OrderBy(e => e.value);
        var newRow = new int[array[0].Length];
        for (var i = 0; i < array.Length; i++)
        {
            int horizontalIndexer = 0;
            foreach (var e in rowIndices)
            {
                newRow[horizontalIndexer++] = array[i][e.index];
            }
            array[i] = newRow.ToArray();
        }
        return array;
    }

Новий всебічний підхід; негативна відповідь все ще впорядковує масиви за елементом at-index. В іншому випадку створюється колекція значень пари-індексу з масиву at-index та сортується за значенням. Це фактично створює набір індексів для того, щоб їх потрібно було додати. Потім для кожного масиву вибираються елементи заздалегідь визначених позицій. Досить обрізання коду і некрасиво, потворно, потворно ** мовчки ридає ** повторне використання вхідних параметрів задіяне, і там ви йдете ... 142 байт.

Знову ж таки, аргумент масиву суворо виконується, додаючи досить багато накладних витрат для викликів .ToArray ().

135 байт стверджують, так ?! Складені C-7.2 підрахунки величин можуть обрізати ще три байти, але tio.run не дозволяє. Отже, це відповідь, яку я вирішив опублікувати для легкої перевірки.


1
Гарна відповідь. У гольф є кілька дрібниць. (a,s)=>може бути каррі a=>s=>. (s<0)?не потрібна дужка, і -s-1може бути ~s. Спробуйте в Інтернеті: 137 байт
Кевін Крейсейс

Солодке! Я ніколи б не дозволив функції повернути ще одну функцію для збереження персонажа, я приємно здивований. Спасибі! Також вагомий випадок кричущого огляду на не оператора та дужки. Я оновив не і круглі дужки, але залишу вам всю честь за функцію повернення функції.
Бародус

1

Java (OpenJDK 8) , 326 байт

(a,b)->{int l=a.length,w=a[0].length,k,m,t,i;if(b>0){for(i=0;i<w;i++){for(k=1;k<(w-i);k++){if(a[b-1][k-1]>a[b-1][k]){for(m=0;m<l;m++){t=a[m][k];a[m][k]=a[m][k-1];a[m][k-1]=t;}}}}}else{b*=-1;for(i=0;i<l;i++){for(k=1;k<(l-i);k++){if(a[k-1][b-1]>a[k][b-1]){for(m=0;m<w;m++){t=a[k][m];a[k][m]=a[k-1][m];a[k-1][m]=t;}}}}}return a;}

Спробуйте в Інтернеті!

Добре, хлопці, це питання мене дуже засмутило, і я опублікував свою відповідь, ЗНАЮЧИ, що я щось забуваю, на щастя, у нас є легенди на кшталт Кевіна Круїссена , щоб допомогти нам :)

Java (OpenJDK 8) , 281 байт

a->b->{int l=a.length,w=a[0].length,k,m,t,i;if(b>0)for(i=0;i<w;i++)for(k=0;++k<w-i;)for(m=0;a[b-1][k-1]>a[b-1][k]&m<l;a[m][k]=a[m][k-1],a[m++][k-1]=t)t=a[m][k];else for(b*=-1,i=0;i<l;i++)for(k=0;++k<l-i;)for(m=0;a[k-1][b-1]>a[k][b-1]&m<w;a[k][m]=a[k-1][m],a[k-1][m++]=t)t=a[k][m];}

Спробуйте в Інтернеті!


Я ще не переглянув власне алгоритм, але ви можете зберегти 35 байт, видаливши всі дужки і помістивши все в циклі (включаючи внутрішній if-оператор). Спробуйте в Інтернеті: 291 байт EDIT: Тут з пробілами, щоб ви могли чіткіше побачити зміни, які я вніс.
Кевін Кройсейсен

@KevinCruijssen Я знав, що мені щось не вистачає
X1M4L

Крім того, ви можете зробити це введенням кришів a->b->замість (a,b)->та видалити- returnзаяву, оскільки ви змінюєте масив введення. 281 байт Хоча приємна відповідь. +1 від мене. Я робив виклик у 05AB1E, але цього разу навіть не спробував би його на Java. ;)
Кевін Круїссен





1

Червоний , 190 185 байт

func[b n][t: func[a][c: length? a/1 a: to[]form a
d: copy[]loop c[append/only d extract a c take a]d]d: does[if n > 0[b: t b]]d
m: absolute n sort/compare b func[x y][x/(m) < y/(m)]d b]

Спробуйте в Інтернеті!

Пояснення:

f: func [ b n ] [
    t: func [ a ] [                            ; helper transpose function 
        c: length? a/1                         ; c is the length of the rows
        a: to-block form a                     ; flatten the list
        d: copy []                             ; an empty block (list)
        loop c [                               ; do as many times as the number of columns  
            append/only d extract a c          ; extract each c-th element (an entire column)
                                               ; and append it as a sublist to d
            take a                             ; drop the first element
        ] 
        d                                      ; return the transposed block (list of lists)
    ]
   d: does [ if n > 0 [ b: t b ] ]             ; a helper function (parameterless) to transpose 
                                               ; the array if positive n
   d                                           ; call the function  
   m: absolute n                               ; absolute n
   sort/compare b func[ x y ] [ x/(m) < y/(m) ]; sort the array according to the chosen column 
   d                                           ; transpose if positive n
   b                                           ; return the array  
]

Моє фактичне рішення - 175 байт, але воно не працює в TIO. Ось він, працюючи нормаліл в червоній консолі:

Червоний , 175 байт

func[b n][d: does[if n > 0[c: length? b/1 a: to-block form b
t: copy[]loop c[append/only t extract a c take a]b: t]]d
m: absolute n sort/compare b func[x y][x/(m) < y/(m)]d b]

0

VBA (Excel), 205 байт

Так! 2-й найдовший байт! Я повністю не програв: D

Гольф:

Sub d(a)
With ActiveSheet.Sort
  .SortFields.Clear
  .SortFields.Add Key:=IIf(a<0,ActiveSheet.Columns(Abs(a)),ActiveSheet.Rows(Abs(a)))
  .SetRange ActiveSheet.UsedRange
  .Orientation=IIf(a<0,1,2)
  .Apply
End With
End Sub

Це сортує всі дані на відкритому (активному) аркуші за допомогою UsedRange ..., який може бути помилковим, але повинен містити лише відредаговані комірки.

UnGolfed:

Sub d(a)
  'Clear any Sort preferences that already exists
  ActiveSheet.Sort.SortFields.Clear
  'Use the column if A is negative, the row if A is positive
  ActiveSheet.Sort.SortFields.Add Key:=IIf(a < 0, ActiveSheet.Columns(Abs(a)), ActiveSheet.Rows(Abs(a)))
  'Set the area to sort
  ActiveSheet.Sort.SetRange ActiveSheet.UsedRange
  'Orient sideways if sorting by row, vertical if by column
  ActiveSheet.Sort.Orientation = IIf(a < 0, xlTopToBottom, xlLeftToRight)
  'Actually sort it now
  ActiveSheet.Sort.Apply
End Sub

Якщо ви припускаєте, що лист активів аркуш1, то ви можете звести це до 169 байт якSub d(a) With Sheet1.Sort .SortFields.Clear .SortFields.Add IIf(a<0,Columns(Abs(a)),Rows(Abs(a))) .SetRange Sheet1.UsedRange .Orientation=(a<0)+2 .Apply End With End Sub
Тейлор Скотт

Крім того, я думаю, що ви можете сміливо припускати, що немає .SortFieldsвизначених, щоб ви могли також видалити .Sortfields.Clearрядок.
Тейлор Скотт

0

Perl 6 , 43 байти

{($!=$_>0??&[Z]!!*[])o*.sort(*[.abs-1])o$!}

Спробуйте в Інтернеті!

Загорнута функція.

Пояснення

{                                         } # Block returning function composed of
                                       o$!  # 1. Apply $! (transpose or not)
                     o*.sort(*[.abs-1])     # 2. Sort rows by column abs(i)-1
     $_>0??&[Z]                             # 3. If i > 0 transpose matrix
               !!*[]                        #    Else identity function
 ($!=               )                       #    Store in $!

0

Фізика , 45 байт

Дуже схожа на відповідь Арнаульда JS .

F=>n;m:n<0&&Sort[->u:u{~n};m]||Zip@F#Zip@m#-n

Спробуйте в Інтернеті!

Як це працює?

Більш детальне та наочне пояснення можна знайти у зв’язаній відповіді.

F=>n;m:           // Create a function F that takes two arguments, n and m.
       n<0&&      // If n < 0 (i.e. is negative)
Sort[->u{~n};m]   // Sort the rows u of m by the result of the function u[~n].
                  // In short, sort by indexing from the end with n.
||    F#Zip@m#-n  // Else, apply F to Zip[m] and -n. Uses a new feature, binding.
  Zip@            // And transpose the result.


0

Clojure, 91 байт

(fn f[A i](if(< i 0)(sort-by #(nth %(- -1 i))A)(apply map list(f(apply map list A)(- i)))))

Арг, apply map list* 2.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.