Sortowanie bloków wierszy i kolumn w tablicy 2D


15

Biorąc pod uwagę tablicę liczb całkowitych 2D, posortujmy jej wiersze i kolumny w bloki. Oznacza to, że musisz tylko posortować dany wiersz lub kolumnę, ale stosując transformacje potrzebne do posortowania go do każdego innego wiersza lub kolumny w tablicy 2D.

Zasady

  • Wejście będzie dwuwymiarową tablicą liczb całkowitych i 1-indeksowaną liczbą całkowitą. Ta liczba całkowita będzie reprezentować wiersz do posortowania, jeśli liczba jest dodatnia, lub kolumnę do posortowania, jeśli liczba jest ujemna (lub w drugą stronę). Przykład: Biorąc pod uwagę 4x3tablicę (wiersze x kolumny), możesz posortować drugą kolumnę z -2argumentem lub trzeci wiersz z 3argumentem. Ten drugi argument nigdy nie będzie wynosił zero, a jego wartość bezwzględna nigdy nie będzie większa niż odpowiadający mu wymiar tablicy.
  • Wyjściem będzie również tablica liczb całkowitych 2D z zastosowanymi transformacjami do posortowania danego wiersza lub kolumny. Alternatywnie możesz po prostu napisać tablicę do STDOUT.
  • Tablica wyjściowa będzie miała określony wiersz lub kolumnę posortowane w porządku rosnącym. Pamiętaj tylko, że kiedy trzeba zamienić dwie liczby z rzędu, całe kolumny, w których leżą liczby, zostaną zamienione. A kiedy trzeba zamienić dwie liczby w kolumnie, całe rzędy, w których leżą liczby, zostaną zamienione.
  • W przypadku, gdy ta sama liczba pojawia się kilka razy w sortowanym wierszu / kolumnie, istnieje kilka możliwych rozwiązań w zależności od sposobu zamiany wartości, wystarczy postępować odpowiednio z resztą wierszy / kolumn do zamiany.

Przykłady

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]

To jest , więc może wygrać najkrótszy kod dla każdego języka!


To pochodzi z piaskownicy .
Charlie,

Czy możemy zmienić reprezentację liczb całkowitych? ujemny dla wierszy i dodatni dla kolumn?
Luis felipe De jesus Munoz

1
@LuisfelipeDejesusMunoz tak, to jest określone w pytaniu.
Charlie,

Czy wiersz / kolumna może zawierać zduplikowane liczby?
Kevin Cruijssen

@KevinCruijssen tak, zobacz ostatnie przykłady i ostatni punkt zasad.
Charlie,

Odpowiedzi:




5

Matlab, 73 62 47 bajtów

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

Wypróbuj online!

-11 bajtów dzięki @Giuseppe.

-15 bajtów dzięki @LuisMendo.


4

Japt , 18 17 bajtów

ujemna dla wierszy i dodatnia dla kolumn

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

Wypróbuj online!


Nie udaje się Uto, gdy jest ujemne - działa jednak poprzednia 17-bajtowa wersja.
Shaggy

@Shaggy Mój zły, myślałem, że i tak to zadziała, w ogóle nie sprawdziłem
Luis Felipe De Jesus Munoz

Nie jest to jednak zły pomysł, przekazywanie funkcji jako pierwszego argumentu ßtego automatycznie się stosuje U. Może to powodować problemy z próbą przekazania literalnych ciągów znaków, ale mimo to opublikuj sugestię w repozytorium GitHub w celu dalszego zbadania.
Shaggy

4

05AB1E , 25 24 14 bajtów

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

Ogromne -10 bajtów dzięki @Emigna .

Wykorzystuje dodatnią liczbę całkowitą do sortowania wierszy, ujemną dla kolumn.

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

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
Mam diø}Σ¹Ä<è]¹diøtwój podzbiór, więc nie zamieszczam osobnej odpowiedzi.
Emigna,

@Emigna Dang, sprawiasz, że wygląda to tak łatwo .. Teraz, kiedy to widzę, nie mogę uwierzyć, że sam o tym nie myślałem, ale jednocześnie jest genialny .. Dzięki! Ogromne 10 bajtów zaoszczędzonych dzięki tobie.
Kevin Cruijssen

4

JavaScript (ES6), 90 bajtów

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

Wypróbuj online!

W jaki sposób?

JS nie ma natywnej metody transpozycji, dlatego musimy ją zdefiniować:

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

Główna funkcja:

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.=(587613)2)4963)0)t(M.)=(51983)672)3)640)fa(t(M.),-2))=(51972)3)83)6640)fa(M.,2))=t(fa(t(M.),-2)))=(578612)3)493)60)

3

MATL , 17 bajtów

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

Wypróbuj online!

Lub sprawdź wszystkie przypadki testowe

Wyjaśnienie

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 bajtów

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

Wypróbuj online!


Jeśli njest ujemne, wiersze są sortowane na podstawie kolumnyn .

W przeciwnym razie matryca zostanie transponowana, posortowana w ten sam sposób i ponownie transponowana.



1

C # (.NET Core) , 186 bajtów

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

Wypróbuj online!

Nie golfowany:

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

Z funkcji shift skorzystamy dwa razy, więc zmienna funkcji pozwoli zaoszczędzić miejsce. Funkcja przechodzi przez poziomy wymiar tablicy na indeksie i dodaje każdy element na tym indeksie każdej tablicy poziomej do nowej tablicy wyjściowej (poziomo) - podobnie jak w rozwiązaniu Joud firmy Arnoud.

Teraz porządkowanie jest proste, uporządkuj tablicę poziomą według liczby na indeksie (argument -1), opcjonalnie przesuwając tablicę przed i po sortowaniu.

Widząc, jak pytanie dotyczy konkretnie tablic, kilka razy przekształcamy się w tablicę (bardzo, bardzo marnotrawstwo). Czuję się trochę głupio, używając tak pełnego języka w hehe golfowym.


1

C # (.NET Core) , 142/139 138/135 bajtów (i jeszcze jedno -1 przez Kevina)

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

Wypróbuj online!

Nie golfowany:

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

Nowe całościowe podejście; odpowiedź przecząca wciąż porządkuje tablice według elementu po indeksie. W przeciwnym razie tworzona jest kolekcja pary wartość-indeks z tablicy-przy-indeksie i sortowana według wartości. To skutecznie tworzy zbiór indeksów w kolejności dodawania. Następnie dla każdej tablicy wybiera się elementy we wcześniej określonych pozycjach. Jest trochę przycinania kodu i brzydkie, brzydkie, brzydkie ** cicho szloch ** ponowne użycie parametrów wejściowych jest zaangażowane, i proszę bardzo ... 142 bajty.

Ponownie, argument tablic jest ściśle egzekwowany, dodając całkiem sporo narzutu dla wywołań .ToArray ().

135 bajtów roszczenia, co ?! Wnioskowane w krotce C # 7.2 wartości-topy przycinają dodatkowe trzy bajty, ale tio.run nie pozwala. Dlatego jest to odpowiedź, którą postanowiłem opublikować w celu łatwej weryfikacji.


1
Niezła odpowiedź. Jest kilka małych rzeczy do gry w golfa. (a,s)=>może być curry a=>s=>. (s<0)?nie potrzebuje nawiasu i -s-1może być ~s. Wypróbuj online: 137 bajtów
Kevin Cruijssen

Słodkie! Nigdy nie musiałbym pozwolić, aby funkcja zwróciła kolejną funkcję w celu uratowania postaci, jestem mile zaskoczony. Dzięki! Również mocny przypadek rażącego przeoczenia braku operatora i nawiasu. Zaktualizowałem nie i nawiasy, ale pozostawiam wam cały zaszczyt dla funkcji zwracającej funkcję.
Barodus

1

Java (OpenJDK 8) , 326 bajtów

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

Wypróbuj online!

Cóż, chłopaki, to pytanie było dla mnie bardzo frustrujące, a ja opublikowałem swoją odpowiedź WIEDZĄ, że o czymś zapomniałem, na szczęście mamy tutaj legendy takie jak Kevin Cruijssen , które mogą nam pomóc :)

Java (OpenJDK 8) , 281 bajtów

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

Wypróbuj online!


Nie sprawdziłem jeszcze rzeczywistego algorytmu, ale możesz zaoszczędzić 35 bajtów, usuwając wszystkie nawiasy i umieszczając wszystko w pętlach (w tym wewnętrzną instrukcję if). Wypróbuj online: 291 bajtów EDYCJA: Tutaj z wcięciami spacji, aby lepiej widzieć zmiany, które wprowadziłem.
Kevin Cruijssen

@KevinCruijssen Wiedziałem, że czegoś mi brakuje
X1M4L,

Ponadto możesz uczynić go curry wkładem a->b->zamiast (a,b)->i usunąćreturn -statement, ponieważ modyfikujesz tablicę wejściową. 281 bajtów Wciąż ładna odpowiedź. +1 ode mnie Podjąłem wyzwanie w 05AB1E, ale tym razem nawet nie spróbowałbym tego w Javie. ;)
Kevin Cruijssen



1

Kotlin , 192 bajty

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

Wypróbuj online!



1

Czerwony , 190 185 bajtów

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]

Wypróbuj online!

Wyjaśnienie:

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  
]

Moje rzeczywiste rozwiązanie ma 175 bajtów długości, ale nie działa w TIO. Oto działa normalnie w czerwonej konsoli:

Czerwony , 175 bajtów

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 bajtów

Tak! Druga najdłuższa liczba bajtów! Nie straciłem całkowicie: D

Gra w golfa:

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

To sortuje wszystkie dane w otwartym (aktywnym) arkuszu za pomocą UsedRange ..., który może być błędny, ale powinien zawierać tylko edytowane komórki.

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

Jeśli założysz, że arkusz aktywny to arkusz 1, możesz sprowadzić to do 169 bajtów jakoSub 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

Myślę też, że możesz bezpiecznie założyć, że nie ma .SortFieldszdefiniowanego, więc możesz również usunąć .Sortfields.Clearlinię.
Taylor Scott

0

Perl 6 , 43 bajtów

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

Wypróbuj online!

Funkcja curry.

Wyjaśnienie

{                                         } # 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

Physica , 45 bajtów

Bardzo podobny do odpowiedzi JS Arnaulda .

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

Wypróbuj online!

Jak to działa?

Bardziej szczegółowe i wizualne wyjaśnienie można znaleźć w powiązanej odpowiedzi.

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 bajtów

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.