Matriks blok-diagonal dari kolom


16

Terinspirasi oleh Disalin dari pertanyaan ini di Stack Overflow.

Diberi matriks A, buat matriks Bsedemikian rupa sehingga kolom-kolomnya Adisusun secara blok-diagonal. Misalnya diberikan

1 2 3
4 5 6

hasilnya akan

1 0 0
4 0 0
0 2 0
0 5 0
0 0 3
0 0 6

Aturan

Input dan output mungkin dalam bentuk array 2D, array bersarang, atau string dengan pemisah yang berbeda untuk baris dan kolom.

Angka dalam input (matriks A) akan menjadi bilangan bulat positif.

Format unary diperbolehkan, selama nol di output ditampilkan dengan cara yang masuk akal. Misalnya, hasil di atas dapat ditampilkan menggunakan tanda kutip untuk melampirkan masing-masing nomor:

'1' '' ''
'1111' '' ''
'' '11' ''
'' '11111' ''
'' '' '111'
'' '' '111111'

Uji kasus

Input output:

1 2 3
4 5 6

1 0 0
4 0 0
0 2 0
0 5 0
0 0 3
0 0 6


10 20

10  0
 0 20    


10
20

10
20


  1   2   3
 10  20  30
100 200 300

  1   0   0
 10   0   0
100   0   0
  0   2   0
  0  20   0
  0 200   0
  0   0   3
  0   0  30
  0   0 300

 2  4
 6  8
10 12

 2  0
 6  0
10  0
 0  4
 0  8
 0 12

Apakah semua angka dalam A akan berbeda?
Adám

@ Nᴮᶻ Tidak, mereka bisa sama
Luis Mendo

Jawaban:


7

MATL , 6 byte

"@N$Yd

Bekerja dalam versi bahasa saat ini (13.0.0) / kompiler.

Input memiliki bentuk berikut, dengan titik koma sebagai pemisah baris, dan koma atau spasi sebagai pemisah kolom dalam setiap baris:

[1, 2, 3; 4, 5, 6]

Cobalah online!

Penjelasan

"         % implicitly input 2D array and loop over its columns
  @       %   push column
  N$Yd    %   build block-diagonal matrix from all stack contents. Stack contents are
          %   a single column in the first iteration, or a partially built 2D array
          %   and a new column in all other iterations
          % end loop
          % implicit display

Contoh yang berhasil

Pertimbangkan inputnya [1 2 3; 4 5 6]. Untuk loop dimulai dengan "mengambil setiap kolom input. Dalam setiap iterasi, @dorong kolom saat ini ke tumpukan. Jadi dalam iterasi pertama ia mendorong [1; 4]. N$menetapkan bahwa semua konten tumpukan akan digunakan sebagai input dari fungsi berikut Yd,.

Fungsi ini (sesuai dengan MATLAB blkdiag) "menyatukan secara diagonal" inputnya untuk menghasilkan matriks diagonal blok (array 2D). Jadi dalam iterasi pertama Yddibutuhkan satu input dan menghasilkan output yang sama dengan input itu [1; 4],, yang tersisa di stack.

Pada iterasi kedua kolom kedua dari input,, [2; 5]didorong. Sekarang Ydmengambil dua input 2 × 1, yaitu [1; 4]dan [2; 5], dan menghasilkan array 4 × 2 [1 0; 4 0; 0 2; 0 5].

Pada iterasi ketiga Ydmengambil 4 × 2 array terakhir dan kolom ketiga dari input [3; 6],, dan menghasilkan hasil akhir [1 0 0; 4 0 0; 0 2 0; 0 5 0; 0 0 3; 0 0 6].


3

ES6, 65 byte

a=>[].concat(...a[0].map((_,i)=>a.map(b=>b.map((c,j)=>i-j?0:c))))

Dibawa sebagai input dan kembali sebagai output array array.


1
@WashingtonGuedes Peta dalam mengembalikan salinan array 2D asli dengan semua kecuali satu kolom nol. Salinan ini kemudian perlu digabungkan, bukan hanya menjadi elemen dari array 3D luar.
Neil

3

Mathematica, 40 39 Bytes

Kredit ke @Seeq untuk Infixing Flatten.

Transpose[DiagonalMatrix/@#]~Flatten~1&

Input adalah daftar vektor baris yang dibatasi oleh {}tanda kurung. Jadi contoh awal diwakili oleh

{{1,2,3},{4,5,6}}

Hasilkan sebuah array di DiagonalMatrixmana masing-masing memiliki elemen diagonal dari baris input (array 3-D). Transposesehingga Flattenoperasi menghilangkan pasangan braket yang benar untuk memberikan matriks yang diinginkan (sekarang array 2-D).


1
Tidak akan DiagonalMatrix/@#bekerja Dan, dengan ekstensi,Transpose[DiagonalMatrix/@#]~Flatten~1&
seequ

Tangkapan yang bagus, saya bermaksud memperbaikinya setelah menggulungnya. Tidak berpikir untuk menggunakan itu Infix Flatten. +1.
IPoiler


1

Jelly, 13 byte

ZLR’×L0ẋ;"Zz0

Cobalah online!

Bagaimana itu bekerja

ZLR’×L0ẋ;"Zz0  Main link. Input: M (matrix)

Z              Transpose M.
 L             Get the length of the result. This yields the number of M's columns.
  R            Range; for m columns, yield [1, ..., m].
   ’           Decrement to yield [0, ..., m-1].
    ×L         Multiply each by the length (number of rows) of M.
               This yields [0, n, ..., n(m-1)], where n is the number of rows.
      0ẋ       Push a list of lists of zeroes.
               First element is [], last is n(m-1) zeroes.
        ;"Z    Prepend the kth vector of zeroes to the kth column of M.
           z0  Zip, filling the non-rectangular 2D array with zeroes.

1

Mathematica, 111 byte

Join@@@ReplacePart[Table[0,#2/#3]~Table~#3~Table~#3,Table[{n,n}->#[[n]],{n,#3}]]&[Length@#,Length@Flatten@#,#]&

Apa sintaks inputnya? Ini melempar Tabledan Partkesalahan ketika menggunakan notasi matriks MMA standar dan menghasilkan array dimensi campuran.
IPoiler

1

Ruby, 81 78 76 62 byte

->a{i=-1;a[0].flat_map{i+=1;a.map{|b|x=b.map{0};x[i]=b[i];x}}}

mendesah secara manual melacak indeks lebih pendek dari with_index.

->a{
i=-1;            # index of the flat_map
a[0]             # duplicate all rows as many times as necessary
.flat_map{       # we're wrapping each "group" of original rows with yet another
                 #  array, so we need to flat_map to get rid of those
i+=1;            # increment the index of the current subarray
a.map{|b|        # for each sub-subarray (these are the rows)...
x=b.map{0};      # zero everything out
x[i]=b[i];       # replace the desired elements
x}}}             # finally, return the modified array

1

R, 41 byte

pryr::f(Matrix::.bdiag(plyr::alply(a,2)))

Asumsikan pryr, Matrixdan plyrpaket diinstal.

Ini menciptakan fungsi yang mengambil array 2D (a) dan mengembalikan "sparseMatrix" di mana (di mana 0 diwakili sebagai .)

(a=matrix(1:6,ncol=3))
#      [,1] [,2] [,3]
# [1,]    1    3    5
# [2,]    2    4    6
pryr::f(Matrix::.bdiag(plyr::alply(a,2)))(a)
# 6 x 3 sparse Matrix of class "dgTMatrix"
#          
# [1,] 1 . .
# [2,] 2 . .
# [3,] . 3 .
# [4,] . 4 .
# [5,] . . 5
# [6,] . . 6

Penjelasan:

plyr::alply(a,2)setiap kolom adan pengembalian menggabungkan hasil ini dalam daftar

Matrix::.bdiag(lst) membuat blok diagonal matriks dari daftar matriks

pryr::f adalah cara singkat untuk membuat suatu fungsi.

Solusi sepenuhnya berbasis Rdi 59 byte (menggunakan logika jawaban Matlab @ PieCot):

function(a){l=dim(a);diag(l[2])%x%matrix(1,nrow=l[1])*c(a)}

1

MATLAB, 69 68 byte

   function h=d(a)
   [r,c]=size(a);h=repmat(a,c,1).*kron(eye(c),~~(1:r)')

Satu byte dicukur habis: terima kasih kepada Luis Mendo :)


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.