Ordinamento a blocchi di righe e colonne in un array 2D


15

Dato un array 2D di numeri interi, ordiniamo le sue righe e colonne in blocchi. Ciò significa che devi solo ordinare una determinata riga o colonna, ma applicando le trasformazioni necessarie per ordinarlo su ogni altra riga o colonna nell'array 2D.

Regole

  • L'input sarà un array 2D di numeri interi e un numero intero 1 indicizzato. Questo numero intero rappresenterà la riga da ordinare se il numero è positivo o la colonna da ordinare se il numero è negativo (o viceversa). Esempio: dato un 4x3array (righe x colonne) è possibile ordinare la seconda colonna con un -2argomento o la terza riga con un 3argomento. Questo secondo argomento non sarà mai zero e il suo valore assoluto non sarà mai maggiore della dimensione corrispondente dell'array.
  • L'output sarà anche un array 2D di numeri interi con le trasformazioni necessarie applicate per ordinare la riga o colonna specificata. In alternativa puoi semplicemente scrivere l'array su STDOUT.
  • L'array di output avrà la riga o colonna specificata in ordine crescente. Basta notare che quando è necessario scambiare due numeri di fila, le colonne intere in cui si trovano i numeri verranno scambiate. E quando è necessario scambiare due numeri in una colonna, le intere righe in cui si trovano i numeri verranno scambiate.
  • Nel caso in cui lo stesso numero appaia più volte nella riga / colonna da ordinare, ci saranno diverse soluzioni possibili in base al modo in cui si scambiano i valori, basta fare di conseguenza con il resto delle righe / colonne da scambiare.

Esempi

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]

Questo è , quindi può vincere il codice più breve per ogni lingua!


Questo viene dalla sandbox .
Charlie,

Possiamo cambiare la rappresentazione dei numeri interi? negativo per le righe e positivo per le colonne?
Luis felipe De jesus Munoz,

1
@LuisfelipeDejesusMunoz sì, questo è indicato nella domanda.
Charlie,

Una riga / colonna può contenere numeri duplicati?
Kevin Cruijssen,

@KevinCruijssen sì, vedi gli ultimi esempi e l'ultimo punto delle regole.
Charlie,

Risposte:




5

Matlab, 73 62 47 byte

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

Provalo online!

-11 byte grazie a @Giuseppe.

-15 byte grazie a @LuisMendo.


4

Japt , 18 17 byte

negativo per le righe e positivo per le colonne

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

Provalo online!


Ciò fallisce quando Uè negativo, tuttavia funziona la versione precedente a 17 byte.
Shaggy,

@Shaggy Mio cattivo, anche se avrebbe funzionato comunque, non ho controllato affatto
Luis felipe De jesus Munoz

Non è una cattiva idea, tuttavia, passare una funzione come il primo argomento di ßquello viene applicato automaticamente U. Potrebbe creare problemi con il tentativo di passare stringhe letterali, ma inviare comunque un suggerimento al repository GitHub per ulteriori indagini.
Shaggy,

4

05AB1E , 25 24 14 byte

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

Whopping -10 byte grazie a @Emigna .

Utilizza un input intero positivo per ordinare le righe, negativo per le colonne.

Provalo online o verifica tutti i casi di test .

Spiegazione:

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
Ho capito diø}Σ¹Ä<è]¹diøche è un tuo sottoinsieme, quindi non sto postando una risposta separata.
Emigna,

@Emigna Dang, lo fai sembrare così facile .. Ora che lo vedo non riesco a credere di non averci pensato nemmeno io, ma è geniale allo stesso tempo .. Grazie! Un enorme 10 byte salvati grazie a te.
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))

Provalo online!

Come?

JS non ha un metodo di trasposizione nativo, quindi dobbiamo definirne uno:

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

Funzione principale:

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 byte

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

Provalo online!

Oppure verifica tutti i casi di test

Spiegazione

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 byte

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

Provalo online!


Se nè negativo, le righe vengono ordinate in base alla colonna n.

Altrimenti la matrice viene trasposta, ordinata allo stesso modo e nuovamente trasposta.



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

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

La funzione shift useremo due volte, quindi una variabile di funzione farà risparmiare spazio. La funzione scorre attraverso la dimensione orizzontale dell'array su indice e aggiunge tutti gli elementi su quell'indice in ciascun array orizzontale a un nuovo array di output (in orizzontale), più o meno come nella soluzione JS di Arnoud.

Ora l'ordinamento è semplice, ordina l'array orizzontale in base al numero in corrispondenza dell'indice (argomento -1), spostando facoltativamente l'array prima e dopo l'ordinamento.

Visto come la domanda parla specificamente di array, ci convertiamo in array un paio di volte (molto, molto dispendioso). Sentirsi un po 'sciocco usare un linguaggio così prolisso nel codice golf hehe.


1

C # (.NET Core) , 142/139 138/135 byte (e ancora un altro -1 di 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()

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

Nuovo approccio all-in-line; la risposta negativa ordina ancora array per element-at-index. Altrimenti, viene creata una raccolta di coppia indice-valore dell'array-at-index e ordinata per valore. Questo crea efficacemente una raccolta di indici in ordine di dover essere aggiunto. Quindi, per ciascun array, vengono selezionati gli elementi nelle posizioni predeterminate. Abbastanza un po 'di rifilatura del codice e il brutto, brutto, brutto ** singhiozzo silenzioso ** è coinvolto il riutilizzo dei parametri di input, e il gioco è fatto ... 142 byte.

Ancora una volta, l'argomento array viene applicato rigorosamente, aggiungendo un certo sovraccarico per le chiamate .ToArray ().

135 byte sostengono, eh ?! Le tuple di valore dedotte da C # 7.2 eliminerebbero altri tre byte, ma tio.run non lo consente. Pertanto, questa è la risposta che ho deciso di pubblicare per una facile verifica.


1
Bella risposta. Ci sono alcune piccole cose da golf. (a,s)=>può essere un curry a=>s=>. (s<0)?non ha bisogno della parentesi e -s-1può esserlo ~s. Provalo online: 137 byte
Kevin Cruijssen,

Dolce! Non avrei mai lasciato che la funzione restituisse l'ennesima funzione per salvare un personaggio, sono piacevolmente sorpreso. Grazie! Anche un caso forte di trascurare palesemente il non operatore e la parentesi. Ho aggiornato il non e le parentesi, ma ti lascerò tutto l'onore per la funzione di ritorno.
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;}

Provalo online!

Bene ragazzi, questa domanda è stata molto frustrante per me, e ho pubblicato la mia risposta SAPERE Stavo dimenticando qualcosa, per fortuna abbiamo leggende come Kevin Cruijssen qui per aiutarci :)

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

Provalo online!


Non ho ancora esaminato l'algoritmo reale, ma puoi salvare 35 byte rimuovendo tutte le parentesi e inserendo tutto all'interno dei loop (inclusa l'istruzione if interna). Provalo online: 291 byte EDIT: qui con rientri di spazio modo da poter vedere più chiaramente i cambiamenti che ho fatto.
Kevin Cruijssen,

@KevinCruijssen Sapevo che mi mancava qualcosa
X1M4L

Inoltre, è possibile renderlo un input di curry a->b->anziché (a,b)->e rimuovere lo return-statement, poiché si sta modificando l'array di input. 281 byte Ancora una bella risposta, comunque. +1 da me. Ho fatto la sfida in 05AB1E, ma questa volta non l'avrei nemmeno provata in Java. ;)
Kevin Cruijssen,



1

Kotlin , 192 byte

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

Provalo online!



1

Rosso , 190 185 byte

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]

Provalo online!

Spiegazione:

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  
]

La mia soluzione effettiva è lunga 175 byte, ma non funziona in TIO. Eccolo, funzionando normalmente nella console rossa:

Rosso , 175 byte

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 byte

Sìì! Conteggio byte 2 più lungo! Non ho perso completamente: D

golfed:

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

Questo ordina tutti i dati sul foglio di lavoro aperto (attivo) usando UsedRange ... che può essere errato, ma dovrebbe contenere solo celle che sono state modificate.

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

Se supponi che il foglio attivo sia foglio1, puoi ottenere questo fino a 169 byte comeSub 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

Inoltre, penso che puoi tranquillamente presumere che non ci siano .SortFieldsDefiniti in modo da poter rimuovere anche la .Sortfields.Clearlinea.
Taylor Scott

0

Perl 6 , 43 byte

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

Provalo online!

Funzione al curry.

Spiegazione

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

Molto simile alla risposta JS di Arnauld .

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

Provalo online!

Come funziona?

Una spiegazione più elaborata e visiva può essere trovata nella risposta collegata.

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

J , 32 byte

f=.[/:({"1~<:)
g=.(f&.|:|)`f@.(0<])

Provalo online!

Nota: g=.il verbo principale non conta.

Una versione esplicita per gli stessi byte

J , 32 byte

4 :'y(]/:{"1)&.(|:^:(x<0))~<:|x'

Provalo online!


0

Clojure, 91 byte

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.