Diamondize a Matrix


20

Diberikan matriks, menampilkan representasi dari matriks di mana elemen kiri atas di atas, anti-diagonal adalah baris tengah dan elemen kanan bawah di bagian bawah.

Sebagai contoh, pertimbangkan matriks berikut:

1 2 3
4 5 6
7 8 9

Versi berlian dari matriks ini adalah:

  1
 4 2
7 5 3
 8 6
  9

Masukan dan keluaran

Matriks input akan diberikan sebagai daftar daftar (atau yang serupa dengan bahasa pilihan Anda). Keluaran harus berupa daftar daftar juga.

Matriks hanya akan berisi bilangan bulat positif.

Matriks input tidak harus persegi.

Matriks input akan setidaknya 1 × 1.

Uji Kasus

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

Mencetak gol

Ini adalah , jadi jawaban tersingkat dalam byte menang.



Terkait / Generalisasi. (Tidak akan menganggapnya sebagai penipuan, karena yang memungkinkan array kasar dan diperlukan rotasi dengan kelipatan 45 derajat.)
Martin Ender

Jawaban:


19

J, 7 byte

<@|./.

Ini adalah kata kerja monadik tanpa nama yang mengambil matriks dan mengembalikan daftar antidiagonal:

   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│
└─┴───┴─────┴─────┴────┴──┘

Uji di sini.

Penjelasan

  • /.adalah built-in J untuk menerapkan fungsi pada masing-masing anti-diagonal. Sayangnya, anti-diagonal ini diberikan dalam urutan yang berlawanan dari yang kita inginkan di sini.
  • Dalam <@|., pertama-tama kita menerapkan |.yang membalikkan anti-diagonal dan kemudian <ke kotak itu (yang merupakan satu-satunya cara untuk mengembalikan array yang compang-camping di J, karena array normal selalu persegi panjang, sehingga antidiagonal akan diisi dengan nol).

Itu gila dan cantik. Saya akan meluangkan waktu untuk mempelajari bahasa ini suatu hari nanti.
Kerinduan mesin

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

Uji di Ideone .


Python + NumPy, 69 byte

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

Mengharapkan array NumPy 2D sebagai input dan mengembalikan daftar array NumPy. Uji di Ideone .


4

Jelly, 7 byte

ṚŒDṙZL$

Cobalah online!

Penjelasan

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

Tidak tahu Jelly, tapi itu bukan 7 byte jika itu memerlukan operan unicode.
Guidobot

5
@Guidobot Jelly menggunakan halaman kode khusus yang mengkodekan masing-masing 256 karakter yang dimengerti sebagai satu byte.
Dennis

4

Mathematica, 58 56 byte

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

Fungsi anonim, mengambil array bersarang.


Anda dapat menyimpan satu dengan Length[#]mana adalah \[Transpose]. Dan mungkin yang lain dari aliasing Length.
Sp3000

Atau Length@#&@@#untuk ASCII hanya pada jumlah byte yang sama.
Martin Ender

3

CJam, 17 byte

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

Blok tanpa fungsi (fungsi) yang mengharapkan matriks pada tumpukan dan menggantinya dengan antidiagonalnya.

Uji di sini.

Ini (ditemukan oleh Sp3000) berfungsi untuk jumlah byte yang sama:

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

Penjelasan

Ini paling baik dijelaskan dengan sebuah contoh. Pertimbangkan input:

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

Sertakan 0s, zip, lalu hapus elemen falsy. Mengembalikan daftar tupel. Ini digunakan map(None,...)untuk melakukan zip_longest (melapisi titik yang hilang dengan None) dan filter(None,...)untuk menghapus elemen palsu.

Mengganggu, kita perlu menambahkan []baris tambahan ke mapuntuk menjamin bahwa daftar tupel dikembalikan, karena map(None,*[[1]])pengembalian [1]daripada [(1,)]matriks 1x1. Baris tambahan dihilangkan oleh filtermeskipun.

(Terima kasih kepada @ Dennis untuk -1 byte)


3

Ruby, 68 66 byte

Fungsi anonim.

->l{i=-1;k=[];l.map{|r|i-=j=-1;r.map{|e|k[i+j+=1]=[e,*k[i+j]]}};k}
  • Karena cara operator percikan bekerja, saya dapat menghemat 2 byte dengan menghentikan penambahan array.

2

Mathematica, 60 byte

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

di mana karakter Unicode yang dibaca Mathematica sebagai \[Transpose]operator postfix .

Ini sedikit lebih lama daripada solusi Mathematica lainnya, tetapi saya pikir saya akan mempostingnya karena tidak menggunakan Diagonalsbuilt-in dan menggunakan pendekatan yang sama sekali berbeda.

Penjelasan

MapIndexed[List,#,{2}]

Ini pertama transposes matriks (sedemikian rupa sehingga antidiagonals muncul dalam urutan yang benar jika matriks itu diratakan). Kemudian kita memetakan Listsel-sel matriks bersama dengan indeks, yang mengubah setiap elemen matriks imenjadi di {i, {x, y}}mana xdan ymerupakan koordinat elemen dalam matriks.

Join@@...

Ini mendatar dimensi terluar, sehingga kita sekarang memiliki daftar datar elemen matriks (dengan koordinatnya) dalam urutan kolom-utama.

GatherBy[..., Tr@*Last]

Ini mengelompokkan elemen-elemen tersebut dengan jumlah koordinatnya. Perhatikan bahwa antidiagonal adalah garis konstanta x+y, jadi ini sesuai dengan pengelompokan yang kita inginkan. Urutan dalam setiap grup dipertahankan. Sekarang kita hanya perlu menyingkirkan koordinat lagi. Ini dilakukan melalui agak samar:

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

Ini memetakan fungsi di #&@@@#&atas setiap grup, yang dengan sendirinya berlaku #& untuk setiap elemen dalam grup, dan #hanyalah argumen pertama, yaitu elemen matriks asli.


Ada penjelasan mengapa dibaca \[transpose]?
Fatalkan tanggal

1
@Fatalize Ini adalah codepoint Unicode yang digunakan pribadi, dan mesin terbang yang terkait dengan codepoint ini adalah superscript T: reference.wolfram.com/language/ref/character/Transpose.html ... \[Transpose]hanyalah transliterasi ASCII dari karakter Unicode itu. Menyalin karakter Unicode atau transliterasi ke dalam Mathematica akan berhasil.
Martin Ender

2

Oktaf, 77 byte

Dengan sedikit penyalahgunaan accumarrayfungsi:

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

Ini mendefinisikan fungsi anonim. Untuk menggunakannya, tetapkan ke variabel atau gunakan ans.

Input adalah matriks dengan :pemisah baris. Output adalah array sel yang berisi array untuk setiap baris (setara dengan oktaf untuk array bergerigi). Ini ditampilkan oleh Oktaf yang menunjukkan indeks array sel dan isi dari masing-masing sel. Coba di sini .

Untuk menampilkan hasil yang dipisahkan hanya oleh spasi dan baris baru: 83 byte

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

Anda juga bisa mencobanya di sini .


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

Disimpan 11 byte berkat @Neil!

Bekerja di Firefox 30+. Mengambil array array.


Algoritma yang bagus, tetapi Anda dapat menggunakan a.concat(a[0]).slice(1)untuk mendapatkan array dengan panjang yang tepat. Juga, [for(of)]bukan ES6; Saya biasanya menuliskannya sebagai (Firefox 30+) atau semacamnya.
Neil

@Neil Wow, saya merasa sedikit konyol tidak mencari tahu untuk digunakan concatdan slice. Terima kasih!
user81655

2

Oktaf, 63 62 byte

Dihapus satu byte berkat @DonMue ... @LuisMendo!

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

Saya menempuh rute yang membosankan dan membuat antidiagonal menjadi hijau.

Sampel dijalankan pada ideone .


Saya pikir Anda dapat mempersingkat 'uni'ke'un'
Luis Mendo

@LuisMendo Mengapa, ya saya bisa! Terima kasih! :)
gelas kimia

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 menyimpan satu byte. Terima kasih!


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

Selamat Datang di Programming Puzzles & Code Golf! Secara default, kiriman kode tantangan golf harus program atau fungsi dan penggunaan salah satu metode yang disetujui untuk I / O . Cuplikan yang mengharapkan input dalam variabel hardcode tidak diizinkan.
Dennis

Sepertinya Anda dapat mengerjakan ulang solusi pertama yang lambdahanya menggunakan lambda yang dapat Anda gunakan sebagai kiriman Anda.
Alex A.

Saya akan lambda itu
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)](seperti dalam revisi asli Anda) akan sedikit lebih pendek. Juga, Anda harus mengubah A[U][I-U]untuk A[I-U][U]mendapatkan orientasi dari pertanyaan.
Dennis

Saya akan memeriksanya saat kembali ke rumah. Masuk akal
Luis Masuelli

1

Pyth , 41 17 byte

tm_<dx+dYk.T+LaYk

Cobalah online!

Terinspirasi oleh solusi @ Doorknob untuk masalah lain .

Bagaimana itu bekerja:

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

Upaya sebelumnya:

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

Cobalah online!

Bagaimana itu bekerja:

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}

Mengambil array array sebagai input dan mengembalikan array array.

Cobalah

EDIT: Saya lupa untuk output anwser, setelah menambahkan skornya naik menjadi 75.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.