Sắp xếp khối hàng và cột trong một mảng 2D


15

Cho một mảng số nguyên 2D, hãy sắp xếp các hàng và cột của nó theo khối. Điều này có nghĩa là bạn chỉ phải sắp xếp một hàng hoặc cột nhất định, nhưng áp dụng các phép biến đổi cần thiết để sắp xếp nó cho mọi hàng hoặc cột khác trong mảng 2D.

Quy tắc

  • Đầu vào sẽ là một mảng 2D gồm các số nguyên và số nguyên 1 chỉ mục. Số nguyên này sẽ đại diện cho hàng được sắp xếp nếu số dương hoặc cột được sắp xếp nếu số đó là số âm (hoặc theo cách khác mà bạn muốn). Ví dụ: Cho một 4x3mảng (hàng x cột), bạn có thể sắp xếp cột thứ hai bằng một -2đối số hoặc hàng thứ ba với một 3đối số. Đối số thứ hai này sẽ không bao giờ bằng 0 và giá trị tuyệt đối của nó sẽ không bao giờ lớn hơn kích thước tương ứng của mảng.
  • Đầu ra cũng sẽ là một mảng số nguyên 2D với các phép biến đổi cần thiết được áp dụng để sắp xếp hàng hoặc cột đã cho. Ngoài ra, bạn chỉ có thể viết mảng vào STDOUT.
  • Mảng đầu ra sẽ có hàng hoặc cột được chỉ định được sắp xếp theo thứ tự tăng dần. Chỉ cần lưu ý rằng khi bạn cần trao đổi hai số liên tiếp, toàn bộ các cột nơi các số nằm sẽ được hoán đổi. Và khi bạn cần hoán đổi hai số trong một cột, toàn bộ các hàng nơi các số nằm sẽ được hoán đổi.
  • Trong trường hợp cùng một số xuất hiện nhiều lần trong hàng / cột được sắp xếp, sẽ có một số giải pháp có thể theo cách bạn trao đổi các giá trị, chỉ cần thực hiện tương ứng với các hàng / cột còn lại được hoán đổi.

Ví dụ

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]

Đây là , vì vậy có thể mã ngắn nhất cho mỗi ngôn ngữ sẽ giành chiến thắng!


Điều này đến từ hộp cát .
Charlie

Chúng ta có thể thay đổi đại diện số nguyên? âm cho hàng và dương cho cột?
Luis felipe De jesus Munoz

1
@LuisfelipeDejesusMunoz có, điều đó được nêu trong câu hỏi.
Charlie

Một hàng / cột có thể chứa các số trùng lặp?
Kevin Cruijssen

@KevinCruijssen có, xem các ví dụ cuối cùng và điểm cuối cùng của quy tắc.
Charlie

Câu trả lời:





4

Japt , 18 17 byte

âm cho hàng và dương cho cột

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

Hãy thử trực tuyến!


Điều này không thành công khi Uâm - mặc dù phiên bản 17 byte trước đó hoạt động.
Xù xì

@Shaggy Xấu của tôi, dù sao nó cũng sẽ hoạt động, không kiểm tra gì cả
Luis felipe De jesus Munoz

Tuy nhiên, một ý tưởng không tồi, chuyển một hàm làm đối số đầu tiên của ßnó sẽ tự động được áp dụng U. Nó có thể tạo ra các vấn đề với việc cố gắng vượt qua các chuỗi chữ, nhưng vẫn gửi một đề xuất cho repo GitHub để tiếp tục điều tra.
Xù xì

4

05AB1E , 25 24 14 byte

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

Thu được -10 byte nhờ @Emigna .

Sử dụng đầu vào số nguyên dương để sắp xếp các hàng, âm cho các cột.

Dùng thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

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
Tôi đã nhận được diø}Σ¹Ä<è]¹diøđó là một tập hợp con của bạn, vì vậy tôi không đăng một câu trả lời riêng.
Emigna

@Emigna Dang, bạn làm cho nó trông thật dễ dàng .. Bây giờ tôi thấy nó tôi không thể tin rằng tôi đã không nghĩ về điều đó bản thân mình, nhưng nó khéo léo cùng một lúc .. Cảm ơn! Một con số khổng lồ 10 byte được lưu nhờ vào bạn.
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))

Hãy thử trực tuyến!

Làm sao?

JS không có phương thức chuyển vị riêng, vì vậy chúng ta cần định nghĩa một:

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

Chức năng chính:

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?!

Hãy thử trực tuyến!

Hoặc xác minh tất cả các trường hợp thử nghiệm

Giải trình

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

Hãy thử trực tuyến!


Nếu nlà âm, các hàng được sắp xếp dựa trên cột n.

Mặt khác, ma trận được hoán vị, sắp xếp theo cùng một cách và chuyển trở lại một lần nữa.



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

Hãy thử trực tuyến!

Ung dung:

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

Hàm shift chúng ta sẽ sử dụng hai lần, vì vậy một biến hàm sẽ tiết kiệm không gian. Hàm lặp qua kích thước ngang của mảng trên chỉ mục và thêm mọi mục trên chỉ mục đó vào từng mảng ngang vào một mảng đầu ra mới (theo chiều ngang) - giống như trong giải pháp JS của Arnoud.

Bây giờ việc sắp xếp đơn giản, sắp xếp mảng ngang theo số-at-index (đối số -1), tùy ý dịch chuyển mảng trước và sau khi sắp xếp.

Nhìn cách câu hỏi nói về mảng cụ thể, chúng tôi chuyển đổi sang mảng một vài lần (rất, rất lãng phí). Cảm thấy hơi ngớ ngẩn khi sử dụng một ngôn ngữ dài dòng như vậy trong mã golf hehe.


1

C # (.NET Core) , 142/139 138/135 byte (và thêm -1 bởi 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()

Hãy thử trực tuyến!

Ung dung:

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

Phương pháp tiếp cận tất cả nội tuyến mới; câu trả lời phủ định vẫn sắp xếp các mảng theo phần tử tại chỉ mục. Mặt khác, một tập hợp các cặp chỉ số giá trị được tạo ra của mảng-at-index và được sắp xếp theo giá trị. Điều này có hiệu quả tạo ra một tập hợp các chỉ số theo thứ tự phải được thêm vào. Sau đó, cho mỗi mảng, các phần tử trong các vị trí được xác định trước được chọn. Khá nhiều sự cắt xén mã và xấu xí, xấu xí, xấu xí ** âm thầm nức nở ** tái sử dụng các tham số đầu vào có liên quan, và ở đó bạn đi ... 142 byte.

Một lần nữa, đối số mảng được thi hành nghiêm ngặt, thêm khá nhiều chi phí cho các lệnh gọi .ToArray ().

Yêu cầu 135 byte, hả?! Các giá trị được suy ra của C # 7.2 sẽ cắt bớt ba byte, nhưng tio.run không cho phép. Do đó, đây là câu trả lời tôi quyết định đăng để xác minh dễ dàng.


1
Câu trả lời tốt đẹp. Có một vài điều nhỏ để chơi gôn. (a,s)=>có thể là một currying a=>s=>. (s<0)?không cần dấu ngoặc đơn, và -s-1có thể ~s. Dùng thử trực tuyến: 137 byte
Kevin Cruijssen

Ngọt! Tôi chưa bao giờ thông qua việc để chức năng trả về một chức năng khác để cứu nhân vật, tôi rất ngạc nhiên. Cảm ơn! Cũng là một trường hợp mạnh mẽ ngang nhiên nhìn ra toán tử và dấu ngoặc đơn. Tôi đã cập nhật dấu ngoặc đơn và dấu ngoặc đơn, nhưng sẽ để lại cho bạn tất cả danh dự cho hàm trả về hàm.
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;}

Hãy thử trực tuyến!

Chà, câu hỏi này rất khó chịu đối với tôi và tôi đã đăng câu trả lời của mình BIẾT Tôi đã quên điều gì đó, may mắn thay chúng ta có những huyền thoại như Kevin Cruijssen ra đây để giúp chúng ta :)

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

Hãy thử trực tuyến!


Tôi chưa xem xét thuật toán thực tế, nhưng bạn có thể tiết kiệm 35 byte bằng cách xóa tất cả các dấu ngoặc và đặt mọi thứ vào trong các vòng lặp (bao gồm cả câu lệnh if bên trong). Dùng thử trực tuyến: EDIT 291 byte : Ở đây có các vết lõm không gian để bạn có thể thấy rõ hơn những thay đổi tôi đã làm.
Kevin Cruijssen

@KevinCruijssen Tôi biết mình đang thiếu thứ gì đó
X1M4L

Ngoài ra, bạn có thể biến nó thành đầu vào currying a->b->thay vì (a,b)->và loại bỏ return-statement, vì bạn đang sửa đổi mảng đầu vào. 281 byte Vẫn là một câu trả lời hay. +1 từ tôi. Tôi đã thực hiện thử thách trong 05AB1E, nhưng thậm chí sẽ không thử nó trong Java lần này. ;)
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]}}}}

Hãy thử trực tuyến!



1

Màu đỏ , 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]

Hãy thử trực tuyến!

Giải trình:

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  
]

Giải pháp thực tế của tôi dài 175 byte, nhưng nó không hoạt động trong TIO. Đây rồi, làm việc bình thường trong bảng điều khiển Đỏ:

Màu đỏ , 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

Yay! Số byte dài thứ 2! Tôi đã không hoàn toàn thua cuộc: D

Chơi gôn

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

Điều này sắp xếp tất cả dữ liệu trên bảng tính mở (hoạt động) bằng cách sử dụng OLX ... có thể là lỗi, nhưng chỉ nên chứa các ô đã được chỉnh sửa.

Vô song:

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

Nếu bạn cho rằng bảng kích hoạt là sheet1, thì bạn có thể giảm xuống còn 169 byte như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

Ngoài ra, tôi nghĩ rằng bạn có thể giả định một cách an toàn rằng không có .SortFieldsDefined để bạn cũng có thể xóa .Sortfields.Cleardòng.
Taylor Scott

0

Perl 6 , 43 byte

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

Hãy thử trực tuyến!

Chức năng cuộn tròn.

Giải trình

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

Rất giống với câu trả lời JS của Arnauld .

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

Hãy thử trực tuyến!

Làm thế nào nó hoạt động?

Một lời giải thích chi tiết và trực quan hơn có thể được tìm thấy trong câu trả lời được liên kết.

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.