Matrice diagonale a blocchi dalle colonne


16

Ispirato da Copiato da questa domanda in Stack Overflow.

Data una matrice A, crea una matrice in modo Btale che le colonne di Asiano disposte in modo diagonale a blocchi. Ad esempio, dato

1 2 3
4 5 6

l'output sarebbe

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

Regole

L'input e l'output possono essere sotto forma di array 2D, array nidificati o stringhe con diversi separatori per righe e colonne.

I numeri nell'input (matrice A) saranno numeri interi positivi.

È consentito il formato unario, purché gli zeri nell'output vengano visualizzati in modo ragionevole. Ad esempio, il risultato sopra potrebbe essere visualizzato usando le virgolette per racchiudere ogni numero:

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

Casi test

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

Tutti i numeri in A saranno diversi?
Adám,

@Nᴮᶻ No, possono essere uguali
Luis Mendo,

Risposte:


7

MATL , 6 byte

"@N$Yd

Funziona nella versione corrente (13.0.0) della lingua / compilatore.

L'input ha la forma seguente, con punto e virgola come separatore di riga e virgole o spazi come separatori di colonna all'interno di ogni riga:

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

Provalo online!

Spiegazione

"         % 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

Esempio lavorato

Considera l'input [1 2 3; 4 5 6]. Il ciclo for che inizia con "prende ogni colonna dell'input. All'interno di ogni iterazione, @inserisce la colonna corrente nello stack. Quindi nella prima iterazione spinge [1; 4]. N$specifica che tutti i contenuti dello stack verranno utilizzati come input della seguente funzione Yd,.

Questa funzione (corrispondente a MATLAB blkdiag) "concatena diagonalmente" i suoi input per produrre una matrice diagonale a blocchi (array 2D). Quindi nella prima iterazione Ydprende un input e produce un output uguale a quell'input [1; 4], che viene lasciato nello stack.

Nella seconda iterazione [2; 5]viene spinta la seconda colonna dell'input . Ora Ydaccetta due ingressi 2 × 1, vale a dire [1; 4]e [2; 5], e produce l'array 4 × 2 [1 0; 4 0; 0 2; 0 5].

Nella terza iterazione Ydprende l'ultimo array 4 × 2 e la terza colonna dell'input [3; 6]e produce il risultato finale [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))))

Prende come input e restituisce come output una matrice di array.


1
@WashingtonGuedes La mappa interna restituisce una copia dell'array 2D originale con zero tranne una colonna. Queste copie devono quindi essere concatenate, piuttosto che essere solo elementi di un array 3D esterno.
Neil,

3

Mathematica, 40 39 byte

Ringraziamo @Seeq per l' Infixing Flatten.

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

L'input è un elenco di vettori di riga delimitati da {}parentesi. Quindi l'esempio iniziale è rappresentato da

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

Genera un array in DiagonalMatrixcui ognuno ha elementi diagonali dalle righe dell'input (array 3-D). Transposequindi l' Flattenoperazione rimuove le coppie di parentesi corrette per fornire la matrice desiderata (ora array 2-D).


1
Non DiagonalMatrix/@#funzionerebbe? E, per estensione,Transpose[DiagonalMatrix/@#]~Flatten~1&
seequ

Buona cattura, volevo risolverlo dopo averlo arrotolato. Non ho pensato di usare il Infix Flattenperò. +1.
IPoiler,


1

Gelatina, 13 byte

ZLR’×L0ẋ;"Zz0

Provalo online!

Come funziona

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@#,#]&

Qual è la sintassi di input? Ciò genera Tableed Parterrori quando si utilizza la notazione di matrice MMA standard e genera una matrice di dimensioni miste.
IPoiler,

1

Rubino, 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}}}

sospiro Tenere traccia manualmente dell'indice è più breve di 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)))

Presuppone pryr, Matrixeplyr sono installati i pacchetti.

Questo crea una funzione che accetta un array 2D (a) e restituisce un "sparseMatrix" dove (dove gli 0 sono rappresentati come .)

(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

Spiegazione:

plyr::alply(a,2) ogni colonna di a e restituisce combina questi risultati in un elenco

Matrix::.bdiag(lst) crea una matrice diagonale a blocchi da un elenco di matrici

pryr::f è un modo abbreviato per creare una funzione.

Una Rsoluzione completamente base in 59 byte (usando la logica della risposta Matlab di @ 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)')

Un byte è stato rimosso: grazie a Luis Mendo :)


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.