2B dizideki satırları ve sütunları blok sıralama


15

2D tam sayı dizisi verildiğinde, satırlarını ve sütunlarını bloklar halinde sıralayalım. Bu, yalnızca belirli bir satırı veya sütunu sıralamanız gerektiği, ancak 2D dizisindeki diğer tüm satırlara veya sütunlara sıralamak için gereken dönüşümleri uygulamanız gerektiği anlamına gelir.

kurallar

  • Giriş, 2 tam sayı dizisi ve 1 dizinli tam sayı olacaktır. Bu tamsayı, sayı pozitifse sıralanacak satırı veya sayı negatifse (ya da istediğiniz şekilde) sıralanacak sütunu temsil eder. Örnek: Bir 4x3(satır x sütun) dizisi verildiğinde , ikinci sütunu -2bağımsız değişkenle veya üçüncü satırı bağımsız değişkenle sıralayabilirsiniz 3. Bu ikinci argüman asla sıfır olmayacak ve mutlak değeri asla dizinin karşılık gelen boyutundan daha büyük olmayacaktır.
  • Çıktı, aynı zamanda, verilen satırı veya sütunu sıralamak için gereken dönüşümleri içeren bir 2 tam sayı dizisi olacaktır. Alternatif olarak diziyi STDOUT'a yazabilirsiniz.
  • Çıktı dizisi, belirtilen sırada veya sütunda artan sırada sıralanır. Bir satırda iki sayıyı değiştirmeniz gerektiğinde, sayıların yer aldığı tüm sütunların yer değiştireceğini unutmayın. Ve bir sütunda iki sayıyı değiştirmeniz gerektiğinde, sayıların bulunduğu satırların tümü değiştirilir.
  • Aynı sayının sıralanacak sütunda / sütunda birkaç kez göründüğü durumlarda, değerleri takas etme şekline göre birkaç çözüm mümkün olacaktır, sadece değiştirilecek satırların / sütunların geri kalanıyla buna göre yapın.

Örnekler

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]

Bu , bu yüzden her dil için en kısa kod kazanabilir!


Bu sandbox'tan geliyor .
Charlie

Tamsayı gösterimini değiştirebilir miyiz? satırlar için negatif ve sütunlar için pozitif?
Luis felipe De jesus Munoz

1
@LuisfelipeDejesusMunoz evet, bu soruda belirtiliyor.
Charlie

Bir satır / sütun yinelenen sayılar içerebilir mi?
Kevin Cruijssen

@KevinCruijssen evet, kuralların son örneklerine ve son noktalarına bakın.
Charlie

Yanıtlar:





4

Japt , 18 17 bayt

satırlar için negatif ve sütunlar için pozitif

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

Çevrimiçi deneyin!


UOlumsuz olduğunda bu başarısız olur - önceki 17 bayt sürümü de çalışır.
Shaggy

@Shaggy Benim kötü, ben yine de işe yarayacak olsa da, hiç kontrol etmedi
Luis felipe De jesus Munoz

Ancak kötü bir fikir değil, bir işlevi bunun ilk argümanı ßolarak geçirmek otomatik olarak uygulanır U. Değişmez dizeleri geçirmeye çalışmakla ilgili sorunlar oluşturabilir, ancak daha fazla araştırma için yine de GitHub repo'ya bir öneri yayınlayın.
Shaggy

4

05AB1E , 25 24 14 bayt

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

@Emigna sayesinde -10 bayt .

Sütunlar için negatif olan satırları sıralamak için pozitif bir tamsayı girişi kullanır.

Çevrimiçi deneyin veya tüm test senaryolarını doğrulayın .

Açıklama:

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øSizin alt kümeniz olan var , bu yüzden ayrı bir cevap göndermiyorum.
Emigna

@Emigna Dang, çok kolay görüyorsun .. Şimdi görüyorum ki kendim hakkında düşünmediğime inanamıyorum, ama aynı zamanda ustaca .. Teşekkürler! Senin sayesinde 10 bayt kurtardı.
Kevin Cruijssen

4

JavaScript (ES6), 90 bayt

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

Çevrimiçi deneyin!

Nasıl?

JS'nin yerel transpozisyon yöntemi yoktur, bu yüzden birini tanımlamamız gerekir:

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

Ana işlev:

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 bytes

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

Try it online!

Or verify all test cases

Explanation

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 bytes

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

Try it online!


If n is negative, the rows are sorted based on column n.

Otherwise the matrix is transposed, sorted the same way, and transposed back again.



1

C# (.NET Core), 186 bytes

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

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

The shift function we'll use twice, so a function variable will save space. The function iterates through the horizontal dimension of the array on index, and adds every item on that index in of each horizontal array to a new output array (horizontally) - much the same as in Arnoud's JS solution.

Now the ordering is simple, order horizontal array by number-at-index (argument -1), optionally shifting the array before and after sorting.

Seen how the question talks about arrays specifically, we convert to array a few times (very, very wasteful). Feeling a bit silly to use such a verbose language in code golf hehe.


1

C# (.NET Core), 142/139 138/135 bytes (and yet another -1 by 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()

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

New all-inline approach; negative answer still orders arrays by element-at-index. Otherwise, a collection of value-index-pair is created of the array-at-index and sorted by value. This effectively creates a collection of indices in order of having-to-be-added. Then for each array, the elements in the predetermined positions are selected. Quite some trimming of code and ugly, ugly, ugly **silently sobs** reuse of input parameters is involved, and there you go ... 142 bytes.

Again, the arrays argument is strictly enforced, adding quite some overhead for .ToArray() calls.

135 bytes claim, eh?! C# 7.2 inferred value-tuples would trim an additional three bytes, but tio.run doesn't allow. Therefor, this is the answer i decided to post for easy verification.


1
Nice answer. There are a few small things to golf. (a,s)=> can be a currying a=>s=>. (s<0)? doesn't need the parenthesis, and -s-1 can be ~s. Try it online: 137 bytes
Kevin Cruijssen

Sweet! I never would've through of letting the function return yet another function to save a character, i am pleasantly surprised. Thanks! Also a strong case of blatantly overlooking the not operator and parenthesis. I updated the not and parentheses, but will leave you all the honour for the function-returning-function.
Barodus

1

Java (OpenJDK 8), 326 bytes

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

Try it online!

Well guys, this question was very frustrating for me, and I posted my answer KNOWING I was forgetting something, luckily we have legends like Kevin Cruijssen out here to help us out :)

Java (OpenJDK 8), 281 bytes

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

Try it online!


I haven't looked at the actual algorithm yet, but you can save 35 bytes by removing all the brackets and putting everything inside the loops (including the inner if-statement). Try it online: 291 byte EDIT: Here with space indentations so you can more clearly see the changes I did.
Kevin Cruijssen

@KevinCruijssen I knew I was missing something
X1M4L

In addition, you can make it a currying input a->b-> instead of (a,b)-> and remove the return-statement, since you are modifying the input-array. 281 bytes Still a nice answer, though. +1 from me. I did the challenge in 05AB1E, but wouldn't even have tried it in Java this time. ;)
Kevin Cruijssen



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

Try it online!



1

Red, 190 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]

Try it online!

Explanation:

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  
]

My actual solution is 175 bytes long, but it doesn't work in TIO. Here it is, working normalyl in the Red console:

Red, 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]

0

VBA (Excel), 205 bytes

Yay! 2nd longest byte count! I didn't completely lose :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

This sorts all the data on the open (active) worksheet using UsedRange... which can be buggy, but should only contain cells that have been edited.

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

If you assume that the activesheet is sheet1, then you can get this down to 169 bytes as 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
Taylor Scott

Also, I think that you can safely assume that there are no .SortFields Defined so you can remove the .Sortfields.Clear line as well.
Taylor Scott

0

Perl 6, 43 bytes

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

Try it online!

Curried function.

Explanation

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

Very similar to Arnauld's JS answer.

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

Try it online!

How it works?

A more elaborate and visual explanation can be found in the linked answer.

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 bytes

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

Try it online!

Note: The g=. of the main verb doesn't count.

An explicit version for the same bytes

J, 32 bytes

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

Try it online!


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.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.