Block-Sortierung von Zeilen und Spalten in einem 2D-Array

15

Wenn Sie ein 2D-Array von Ganzzahlen haben, sortieren Sie die Zeilen und Spalten in Blöcken. Dies bedeutet, dass Sie nur eine bestimmte Zeile oder Spalte sortieren müssen, aber die zum Sortieren erforderlichen Transformationen auf jede andere Zeile oder Spalte im 2D-Array anwenden müssen.

Regeln

  • Die Eingabe besteht aus einem 2D-Array von Ganzzahlen und einer 1-indizierten Ganzzahl. Diese Ganzzahl repräsentiert die zu sortierende Zeile, wenn die Zahl positiv ist, oder die zu sortierende Spalte, wenn die Zahl negativ ist (oder umgekehrt). Beispiel: Bei einem gegebenen 4x3Array (Zeilen x Spalten) können Sie die zweite Spalte mit einem -2Argument oder die dritte Zeile mit einem 3Argument sortieren . Dieses zweite Argument wird niemals Null sein und sein absoluter Wert wird niemals größer sein als die entsprechende Dimension des Arrays.
  • Die Ausgabe erfolgt auch in Form eines 2D-Arrays mit ganzen Zahlen, wobei die erforderlichen Transformationen zum Sortieren der angegebenen Zeile oder Spalte angewendet werden. Alternativ können Sie das Array auch einfach in STDOUT schreiben.
  • Das Ausgabearray enthält die angegebene Zeile oder Spalte in aufsteigender Reihenfolge. Beachten Sie nur, dass beim Vertauschen von zwei Zahlen in einer Reihe die gesamten Spalten, in denen die Zahlen liegen, vertauscht werden. Und wenn Sie zwei Zahlen in einer Spalte vertauschen müssen, werden die gesamten Zeilen, in denen die Zahlen liegen, vertauscht.
  • In dem Fall, dass dieselbe Nummer mehrmals in der zu sortierenden Zeile / Spalte vorkommt, gibt es mehrere mögliche Lösungen, je nachdem, wie Sie die Werte vertauschen. Tun Sie dies entsprechend für die restlichen auszutauschenden Zeilen / Spalten.

Beispiele

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]

Das ist , also kann der kürzeste Code für jede Sprache gewinnen!

Charlie
quelle
Das kommt aus dem Sandkasten .
Charlie
Können wir die Ganzzahldarstellung ändern? negativ für Zeilen und positiv für Spalten?
Luis Felipe De Jesus Munoz
1
@LuisfelipeDejesusMunoz ja, das steht in der frage.
Charlie
Kann eine Zeile / Spalte doppelte Zahlen enthalten?
Kevin Cruijssen
@ KevinCruijssen ja, siehe letzte Beispiele und letzten Punkt der Regeln.
Charlie

Antworten:

5

Matlab, 73 62 47 Bytes

@(m,i){sortrows(m,-i) sortrows(m',i)'}{(i>0)+1}

Probieren Sie es online!

-11 Bytes dank @ Giuseppe.

-15 Bytes dank @LuisMendo.

DimChtz
quelle
4

Japt , 18 17 Bytes

negativ für Zeilen und positiv für Spalten

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

Probieren Sie es online!

Luis Felipe De Jesus Munoz
quelle
Dies schlägt fehl, wenn Ues negativ ist - die vorherige 17-Byte-Version funktioniert jedoch.
Shaggy
@ Shaggy Meine schlechte, ich dachte, es würde sowieso funktionieren, überhaupt nicht überprüft
Luis Felipe De Jesus Munoz
Es ist jedoch keine schlechte Idee, eine Funktion als erstes Argument zu übergeben ß, die automatisch angewendet wird U. Es könnte Probleme beim Übergeben von Literal-Strings geben, aber dennoch einen Vorschlag an das GitHub-Repo senden, um weitere Nachforschungen anzustellen.
Shaggy
4

05AB1E , 25 24 14 Bytes

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

Satte -10 Bytes dank @Emigna .

Verwendet eine positive Ganzzahleingabe zum Sortieren der Zeilen, eine negative für Spalten.

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

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)
Kevin Cruijssen
quelle
1
Ich habe diø}Σ¹Ä<è]¹diøeine Untergruppe von Ihnen erhalten, daher veröffentliche ich keine separate Antwort.
Emigna
@Emigna Dang, du machst es so einfach. Jetzt, wo ich es sehe, kann ich nicht glauben, dass ich selbst nicht darüber nachgedacht habe, aber es ist gleichzeitig genial. Danke! Satte 10 Bytes wurden dank Ihnen eingespart.
Kevin Cruijssen
4

JavaScript (ES6), 90 Byte

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))

Probieren Sie es online!

Wie?

JS hat keine native Umsetzungsmethode, daher müssen wir eine definieren:

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

Hauptfunktion:

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)
Arnauld
quelle
3

MATL , 17 Bytes

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

Probieren Sie es online!

Oder überprüfen Sie alle Testfälle

Erläuterung

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
Luis Mendo
quelle
2

Python 2 , 71-70 Bytes

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

Probieren Sie es online!


Wenn nnegativ, werden die Zeilen nach Spalten sortiert n.

Ansonsten wird die Matrix transponiert, gleich sortiert und wieder zurücktransponiert.

TFeld
quelle
1

C # (.NET Core) , 186 Byte

(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();}

Probieren Sie es online!

Ungolfed:

    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;
    }

Die Shift-Funktion wird zweimal verwendet, sodass eine Funktionsvariable Platz spart. Die Funktion durchläuft die horizontale Dimension des Arrays im Index und fügt jedes Element in diesem Index in jedem horizontalen Array einem neuen Ausgabearray (horizontal) hinzu - ähnlich wie in Arnouds JS-Lösung.

Jetzt ist die Reihenfolge einfach. Ordnen Sie das horizontale Array nach der Indexnummer (Argument -1) und verschieben Sie das Array optional vor und nach dem Sortieren.

Angesichts der Frage nach Arrays konvertieren wir einige Male zu Arrays (sehr, sehr verschwenderisch). Ich fühle mich ein bisschen albern, eine so wörtliche Sprache im Code Golf zu verwenden, hehe.

Barodus
quelle
1

C # (.NET Core) , 142/139 138/135 Bytes (und noch ein -1 von Kevin)

(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()

Probieren Sie es online!

Ungolfed:

    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;
    }

Neuer All-Inline-Ansatz; Bei einer negativen Antwort werden die Arrays weiterhin nach Element-at-Index sortiert. Andernfalls wird eine Sammlung von Wert-Index-Paaren aus dem Array-at-Index erstellt und nach Wert sortiert. Dies erzeugt effektiv eine Sammlung von Indizes in der Reihenfolge, in der sie hinzugefügt werden müssen. Dann werden für jedes Array die Elemente an den vorbestimmten Positionen ausgewählt. Einiges an Code-Trimmen und hässliches, hässliches, hässliches ** lautloses Schluchzen **. Die Wiederverwendung von Eingabeparametern ist damit verbunden, und los geht's ... 142 Bytes.

Auch hier wird das Array-Argument strikt durchgesetzt, was einen erheblichen Mehraufwand für Aufrufe von .ToArray () bedeutet.

135 Bytes behaupten, nicht wahr ?! C # 7.2-Tupel mit abgeleiteten Werten würden zusätzliche drei Bytes kürzen, aber tio.run lässt dies nicht zu. Aus diesem Grund habe ich mich entschlossen, diese Antwort zur einfachen Überprüfung zu veröffentlichen.

Barodus
quelle
1
Gute Antwort. Es gibt ein paar kleine Dinge zum Golfen. (a,s)=>kann ein currying sein a=>s=>. (s<0)?braucht die Klammer nicht und -s-1kann sein ~s. Versuchen Sie es online: 137 Bytes
Kevin Cruijssen
Süss! Ich hätte es nie geschafft, die Funktion noch eine weitere Funktion zurückgeben zu lassen, um einen Charakter zu speichern. Ich bin angenehm überrascht. Vielen Dank! Auch ein starker Fall von krassem Blick auf den nicht Operator und Klammern. Ich habe das not und die Klammern aktualisiert, aber ich überlasse Ihnen die Ehre für die Funktion-Rückkehr-Funktion.
Barodus
1

Java (OpenJDK 8) , 326 Byte

(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;}

Probieren Sie es online!

Nun Jungs, wurde diese Frage sehr frustrierend für mich, und ich habe meine Antwort zu wissen , ich war etwas zu vergessen, zum Glück haben wir Legenden wie Kevin Cruijssen aus , um uns hier zu helfen :)

Java (OpenJDK 8) , 281 Byte

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];}

Probieren Sie es online!

X1M4L
quelle
Ich habe mir den eigentlichen Algorithmus noch nicht angesehen, aber Sie können 35 Byte sparen, indem Sie alle Klammern entfernen und alles in die Schleifen einfügen (einschließlich der inneren if-Anweisung). Probieren Sie es online aus: 291 Byte BEARBEITEN: Hier mit Leerzeichen, damit Sie die von mir vorgenommenen Änderungen deutlicher sehen können.
Kevin Cruijssen
@ KevinCruijssen Ich wusste, ich hatte etwas verpasst
X1M4L
Darüber hinaus können Sie es einen currying Eingabe machen a->b->statt (a,b)->und das Entfernen return-Anweisung, da Sie die Eingabe-Array modifizieren. 281 Bytes Trotzdem eine schöne Antwort. +1 von mir. Ich habe die Herausforderung in 05AB1E gemeistert, aber diesmal nicht einmal in Java ausprobiert. ;)
Kevin Cruijssen
270 Bytes
Ceilingcat
1

Sauber , 95 Bytes

import StdEnv,Data.List,Data.Func
$n#f=if(n>0)transpose id
=f o sortBy(on(<)\u=u!!(abs n-1))o f

Probieren Sie es online!

Οurous
quelle
1

Kotlin , 192 Bytes

{m:Array<Array<Int>>,s:Int->if(s<0){m.sortBy{it[-s-1]}}else{val a=Array(m[0].size){c->Array(m.size){m[it][c]}}
a.sortBy{it[s-1]}
(0..m.size-1).map{r->(0..m[0].size-1).map{m[r][it]=a[it][r]}}}}

Probieren Sie es online!

JohnWells
quelle
1

Ruby , 69 Bytes

->a,n{f=->x{[0,x.transpose,x][n<=>0]};f[f[a].sort_by{|x|x[n.abs-1]}]}

Probieren Sie es online!

GB
quelle
1

Rot , 190 bis 185 Bytes

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]

Probieren Sie es online!

Erläuterung:

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  
]

Meine aktuelle Lösung ist 175 Byte lang, funktioniert aber in TIO nicht. Hier ist es, normalyl in der roten Konsole zu arbeiten:

Rot , 175 Bytes

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]
Galen Ivanov
quelle
0

VBA (Excel), 205 Byte

Yay! Zweitlängste Byteanzahl! Ich habe nicht ganz verloren: D

Golf gespielt:

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

Dadurch werden alle Daten im geöffneten (aktiven) Arbeitsblatt mit UsedRange ... sortiert. Dies kann fehlerhaft sein, sollte jedoch nur Zellen enthalten, die bearbeitet wurden.

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
seadoggie01
quelle
Wenn Sie davon ausgehen, dass es sich bei dem aktiven Blatt um Blatt 1 handelt, können Sie dies auf 169 Bytes reduzieren alsSub 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
Taylor Scott
Ich denke auch, dass Sie davon ausgehen können, dass es keine .SortFieldsDefinierten gibt, sodass Sie auch die .Sortfields.ClearLinie entfernen können .
Taylor Scott
0

Perl 6 , 43 Bytes

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

Probieren Sie es online!

Curry-Funktion.

Erläuterung

{                                         } # 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 $!
nwellnhof
quelle
0

Physica , 45 Bytes

Sehr ähnlich zu Arnauld's JS Antwort .

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

Probieren Sie es online!

Wie es funktioniert?

Eine ausführlichere und visuellere Erklärung finden Sie in der verknüpften Antwort.

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.
Mr. Xcoder
quelle
0

Clojure, 91 Bytes

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

Argh, apply map list* 2.

NikoNyrh
quelle