Kim cương hóa một ma trận


20

Đưa ra một ma trận, xuất ra một đại diện của ma trận trong đó phần tử trên cùng bên trái ở trên cùng, đường chéo là hàng trung tâm và phần tử bên phải ở dưới cùng.

Ví dụ, hãy xem xét ma trận sau:

1 2 3
4 5 6
7 8 9

Phiên bản kim cương của ma trận này là:

  1
 4 2
7 5 3
 8 6
  9

Đầu vào và đầu ra

Một ma trận đầu vào sẽ được đưa ra dưới dạng một danh sách các danh sách (hoặc bất cứ thứ gì tương tự trong ngôn ngữ bạn chọn). Đầu ra sẽ là một danh sách các danh sách là tốt.

Các ma trận sẽ chỉ chứa các số nguyên dương.

Ma trận đầu vào sẽ không nhất thiết phải là hình vuông.

Ma trận đầu vào sẽ có ít nhất 1 × 1.

Các trường hợp thử nghiệm

Input:  [[1]]
Output: [[1]]

Input:  [[1,2],[3,4]]
Output: [[1],[3,2],[4]]

Input:  [[1,2,3],[4,5,6]]
Output: [[1],[4,2],[5,3],[6]]

Input:  [[11,2,5],[3,99,3],[4,8,15],[16,23,42]]
Output: [[11],[3,2],[4,99,5],[16,8,3],[23,15],[42]]

Chấm điểm

Đây là , vì vậy câu trả lời ngắn nhất bằng byte sẽ thắng.



Liên quan / Tổng quát hóa. (Tuy nhiên, sẽ không coi đó là một bản sao, vì người ta cho phép các mảng bị rách và yêu cầu xoay theo bất kỳ bội số 45 độ nào.)
Martin Ender

Câu trả lời:


19

J, 7 byte

<@|./.

Đây là một động từ không tên được lấy một ma trận và trả về một danh sách các antidiagonals:

   input =. i.3 4
   input
0 1  2  3
4 5  6  7
8 9 10 11

   <@|./. input
┌─┬───┬─────┬─────┬────┬──┐
│0│4 1│8 5 2│9 6 3│10 7│11│
└─┴───┴─────┴─────┴────┴──┘

Kiểm tra nó ở đây.

Giải trình

  • /.được tích hợp sẵn của J để áp dụng một chức năng cho mỗi đường chéo. Thật không may, những đường chéo này được đưa ra theo thứ tự ngược lại với những gì chúng ta muốn ở đây.
  • Trước <@|.tiên, chúng tôi áp dụng |.đảo ngược đường chéo và sau đó <đóng hộp nó (đó là cách duy nhất để trả về một mảng bị rách trong J, vì các mảng thông thường luôn là hình chữ nhật, do đó các antidiagon sẽ được đệm bằng số 0).

Điều đó thật điên rồ và đẹp đẽ. Tôi sẽ dành thời gian để học ngôn ngữ này một ngày nào đó.
máy khao khát

5

Python, 91 byte

e=enumerate
lambda M:[[r[n-i]for i,r in e(M)if-1<n-i<len(r)][::-1]for n,_ in e(M[1:]+M[0])]

Kiểm tra nó trên Ideone .


Python + NumPy, 69 byte

import numpy
lambda M:map(M[::-1].diagonal,range(1-len(M),len(M[0])))

Yêu cầu mảng 2D NumPy làm đầu vào và trả về danh sách các mảng NumPy. Kiểm tra nó trên Ideone .


4

Thạch, 7 byte

ṚŒDṙZL$

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

Giải trình

Ṛ         Reverse the matrix vertically.
 ŒD       Get its diagonals. However these start from 
          the main diagonal, not the corners.
    ZL$   Get the width of the input matrix.
   ṙ      Rotate the list of diagonals left by that many 
          places to obtain the correct order.

Không biết Jelly, nhưng đó không phải là 7 byte nếu nó yêu cầu toán hạng unicode.
Guidobot

5
@Guidobot Jelly sử dụng trang mã tùy chỉnh mã hóa từng trong số 256 ký tự mà nó hiểu là một byte đơn.
Dennis

4

Toán học, 58 56 byte

a=Length;Reverse@#~Diagonal~b~Table~{b,1-a@#,a@#&@@#-1}&

Hàm ẩn danh, lấy các mảng lồng nhau.


Bạn có thể tiết kiệm một với Length[#]nơi \[Transpose]. Và có lẽ khác từ răng cưa Length.
Sp3000

Hoặc Length@#&@@#đối với ASCII chỉ có cùng số byte.
Martin Ender

3

CJam, 17 byte

{eeSf.*::+W%zSf-}

Một khối (hàm) chưa được đặt tên, dự kiến ​​ma trận trên ngăn xếp và thay thế nó bằng các antidiagonals của nó.

Kiểm tra nó ở đây.

Cái này (được tìm thấy bởi Sp3000) hoạt động với cùng số byte:

{_,,Sf*\.+W%zSf-}

Giải trình

Điều này được giải thích tốt nhất với một ví dụ. Xem xét đầu vào:

[[0  1  2  3]
 [4  5  6  7]
 [8  9 10 11]]

ee    e# Enumerate matrix, turning each row [x ... z] into [i [x ... z]] where
      e# i is the vertical index from the top.

[[0 [0  1  2  3]]
 [1 [4  5  6  7]]
 [2 [8  9 10 11]]]

Sf.*  e# Replace each i with a string of i spaces.

[[""   [0  1  2  3]]
 [" "  [4  5  6  7]]
 ["  " [8  9 10 11]]]

::+   e# Prepend these strings to the rows.

[[0  1  2  3]
 ['  4  5  6  7]
 ['  '  8  9 10 11]]   e# Note that each '  corresponds to a space character.

W%    e# Reverse the rows.

[['  '  8  9 10 11]
 ['  4  5  6  7]
 [0  1  2  3]]

z     e# Zip/transpose.

[[ '  '  0]
 [ '  4  1]
 [ 8  5  2]
 [ 9  6  3]
 [10  7]
 [11]]

Sf-   e# Remove spaces from each row.

[[ 0]
 [ 4  1]
 [ 8  5  2]
 [ 9  6  3]
 [10  7]
 [11]]

3

Python 2, 88 87 byte

lambda L:[filter(None,x)[::-1]for x in map(None,[],*[i*[0]+r for i,r in enumerate(L)])]

Chuẩn bị 0s, zip, sau đó loại bỏ các yếu tố giả. Trả về một danh sách các bộ dữ liệu. Điều này sử dụng map(None,...)để thực hiện zip_longest (đệm các điểm bị thiếu với None) và filter(None,...)để loại bỏ các yếu tố giả.

Khó chịu, chúng ta cần thêm một []hàng bổ sung vào mapđể đảm bảo rằng một danh sách các bộ dữ liệu được trả về, vì map(None,*[[1]])trả về [1]thay vì [(1,)]cho ma trận 1x1. Các hàng thêm được loại bỏ filtermặc dù.

(Cảm ơn @Dennis cho -1 byte)


3

Ruby, 68 66 byte

Chức năng ẩn danh.

->l{i=-1;k=[];l.map{|r|i-=j=-1;r.map{|e|k[i+j+=1]=[e,*k[i+j]]}};k}
  • Do cách toán tử splat hoạt động, tôi có thể lưu 2 byte bằng cách gửi bổ sung mảng.

2

Toán học, 60 byte

#&@@@#&/@GatherBy[Join@@MapIndexed[List,#,{2}],Tr@*Last]&

trong đó một ký tự Unicode mà Mathicala đọc là \[Transpose]toán tử postfix .

Thời gian này dài hơn một chút so với giải pháp Mathicala khác nhưng tôi cho rằng tôi đã đăng nó vì nó không sử dụng tích Diagonalshợp sẵn và sử dụng một cách tiếp cận hoàn toàn khác.

Giải trình

MapIndexed[List,#,{2}]

Điều này đầu tiên chuyển đổi ma trận (sao cho các antidiagonals xuất hiện theo đúng thứ tự nếu ma trận được làm phẳng). Sau đó, chúng tôi ánh xạ Listqua các ô của ma trận cùng với chỉ mục, biến mỗi phần tử ma trận ithành {i, {x, y}}vị trí xylà tọa độ của phần tử trong ma trận.

Join@@...

Điều này làm phẳng kích thước ngoài cùng, để bây giờ chúng ta có một danh sách phẳng các phần tử ma trận (với tọa độ của chúng) theo thứ tự chính của cột.

GatherBy[..., Tr@*Last]

Điều này nhóm các yếu tố đó bằng tổng tọa độ của chúng. Lưu ý rằng các antidiagonals là các dòng không đổi x+y, vì vậy đây chính xác là nhóm chúng ta muốn. Thứ tự trong mỗi nhóm được bảo tồn. Bây giờ chúng ta chỉ cần thoát khỏi tọa độ một lần nữa. Điều này được thực hiện thông qua khá khó hiểu:

#&@@@#&/@...

Điều này ánh xạ hàm #&@@@#&trên mỗi nhóm, chính nó áp dụng #& cho từng phần tử trong nhóm và #chỉ đơn giản là đối số đầu tiên, tức là phần tử ma trận gốc.


Bất kỳ lời giải thích như tại sao được đọc là \[transpose]?
Gây tử vong vào

1
@Fatalize Đó là một dùng riêng Unicode điểm mã, và các glyph Mathematica cộng với điểm mã này là một superscript T: reference.wolfram.com/language/ref/character/Transpose.html ... \[Transpose]chỉ đơn giản là phiên âm ASCII đó ký tự Unicode. Sao chép ký tự Unicode hoặc phiên âm vào Mathicala sẽ hoạt động.
Martin Ender

2

Octave, 77 byte

Với một chút lạm dụng accumarraychức năng:

@(M)char(accumarray(((1:size(M,1))+(0:size(M,2)-1)')(:),M(:),[],@(x){num2str(x')}))

Điều này xác định một chức năng ẩn danh. Để sử dụng nó, gán cho một biến hoặc sử dụng ans.

Đầu vào là ma trận với :dấu phân cách hàng. Đầu ra là một mảng ô chứa một mảng cho mỗi hàng (Octave tương đương với các mảng lởm chởm). Điều này được hiển thị bởi Octave hiển thị các chỉ số của mảng ô và nội dung của từng ô. Hãy thử nó ở đây .

Để chỉ hiển thị kết quả được phân tách bằng dấu cách và dòng mới: 83 byte

@(M)char(accumarray(((1:size(M,1))+(0:size(M,2)-1)')(:),M(:),[],@(x){num2str(x')}))

Bạn cũng có thể thử nó ở đây .


2

JavaScript (Firefox), 86 75 byte

a=>a.concat(a[0]).slice(1).map((_,i)=>[for(v of a)if(n=v[i--])n].reverse())

Đã lưu 11 byte nhờ @Neil!

Hoạt động trong Firefox 30+. Có một mảng các mảng.


Thuật toán đẹp, nhưng bạn có thể sử dụng a.concat(a[0]).slice(1)để có được một mảng có độ dài phù hợp. Ngoài ra, [for(of)]không phải là ES6; Tôi thường viết nó dưới dạng (Firefox 30+) hoặc một số như vậy.
Neil

@Neil Wow, tôi cảm thấy hơi ngớ ngẩn khi không tìm ra để sử dụng concatslice. Cảm ơn!
dùng81655

2

Octave, 63 62 byte

Đã xóa một byte nhờ @DonMue ... @LuisMendo!

@(a)cellfun(@(x)x(x>0)',num2cell(spdiags(flipud(a)),1),'un',0)

Tôi đã đi theo con đường nhàm chán và mung các antidiagonals.

Mẫu chạy trên ideone .


Tôi nghĩ bạn có thể rút ngắn 'uni'xuống'un'
Luis Mendo

@LuisMendo Tại sao, vâng tôi có thể! Cảm ơn! :)
cốc

2

Haskell, 83 82 byte

r=zip[0..]
\o->fst$span(any(>0))[reverse[e|(x,t)<-r o,(v,e)<-r t,x+v==a]|a<-[0..]]

nimi đã lưu một byte. Cảm ơn!


1

Python, 128 byte (numpy)

(lambda A: (lambda A,S:[[A[U][I-U] for U in range(min(S[1]-1,I),max(I-S[0]+1,0)-1,-1)] for I in range(S[1]+S[0]-1)])(A,A.shape))

Chào mừng bạn đến với Câu đố lập trình & Code Golf! Theo mặc định, đệ trình để mã thách thức sân golf phải được các chương trình hoặc các chức năng và một sử dụng các phương pháp đã được phê duyệt cho I / O . Một đoạn mã dự kiến ​​đầu vào trong một biến mã hóa cứng không được phép.
Dennis

Có vẻ như bạn có thể làm lại giải pháp đầu tiên sử dụng lambdathành lambda mà bạn có thể sử dụng làm bài nộp của mình.
Alex A.

Tôi sẽ lambda nó
Luis Masuelli

lambda A:[[A[U][I-U]for U in range(max(I-len(A)+1,0),min(len(A[0])-1,I)+1)]for I in range(len(A+A[0])-1)](như trong phiên bản gốc của bạn) sẽ ngắn hơn một chút. Ngoài ra, bạn nên thay đổi A[U][I-U]để A[I-U][U]có được định hướng từ câu hỏi.
Dennis

Tôi sẽ kiểm tra nó khi trở về nhà. Làm cho ý nghĩa
Luis Masuelli

1

Bình thường , 41 17 byte

tm_<dx+dYk.T+LaYk

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

Lấy cảm hứng từ giải pháp của @ Doorknob cho một vấn đề khác .

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

tm_<dx+dYk.T+LaYk
            +L      prepend to each subarray...
              aYk   (Y += ''). Y is initialized to [],
                    so this prepends [''] to the first
                    subarray, ['', ''] to the second, etc.
                    ['' 1  2  3
                     '' '' 4  5  6
                     '' '' '' 7  8  9
                     '' '' '' '' 10 11 12
                     '' '' '' '' '' 13 14 15]
          .T        transpose, giving us
                    ['' '' '' '' ''
                     1  '' '' '' ''
                     2  4  '' '' ''
                     3  5  7  '' ''
                     6  8  10 ''
                     9  11 13
                     12 14
                     15]
 m_<dx+dYk          removes all empty strings in the
                    subarrays while reversing each one
t                   remove the first subarray

Lần thử trước:

JlQKlhQm_m@@Qk-dk}h.MZ,0-dtKh.mb,tJdUt+JK

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

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

JlQKlhQm_m@@Qk-dk}h.MZ,0-dtKh.mb,tJdUt+JK    input array stored as Q
JlQ                                          J = len(Q)
   KlhQ                                      K = len(Q[0])
       m                            Ut+JK    list for d from 0 to J+K-1:
        _m       }AAAAAAAAAABBBBBBBB             reversed list for k from A to B, where:
                  h.MZ,0-dtK                       A = max(0, d-(K-1))
                       0-dtK                               0  d-(K-1)
                            h.mb,tJd               B = min(J-1, d)
                                 tJd                       J-1  d
          @@Qk-dk                                    Q[k][d-k]

1

Groovy, 77 73 75

{i->o=[].withDefault{[]};a=0;i.each{b=0;it.each{o[a+b++].add(0,it)};a++};o}

Lấy mảng các mảng làm đầu vào và trả về mảng của mảng.

Thử nó

EDIT: Tôi đã quên xuất ra anwser, sau khi thêm nó, điểm số lên tới 75.

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.