Blockdiagonale Matrix aus Spalten

16

Inspiriert von Kopiert von dieser Frage bei Stack Overflow.

AErstellen Sie bei einer gegebenen Matrix eine Matrix B, bei der die Spalten von Ablockdiagonal angeordnet sind. Zum Beispiel gegeben

1 2 3
4 5 6

die Ausgabe wäre

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

Regeln

Eingabe und Ausgabe können in Form von 2D-Arrays, verschachtelten Arrays oder Zeichenfolgen mit unterschiedlichen Trennzeichen für Zeilen und Spalten erfolgen.

Zahlen in der Eingabe (Matrix A) sind positive ganze Zahlen.

Unäres Format ist zulässig, solange Nullen in der Ausgabe in angemessener Weise angezeigt werden. Zum Beispiel könnte das obige Ergebnis mit Anführungszeichen angezeigt werden, um jede Zahl einzuschließen:

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

Testfälle

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
Luis Mendo
quelle
Werden alle Zahlen in A unterschiedlich sein?
Adám
@ Nᴮᶻ Nein, sie können gleich sein
Luis Mendo

Antworten:

7

MATL , 6 Bytes

"@N$Yd

Funktioniert in der aktuellen Version (13.0.0) der Sprache / des Compilers.

Die Eingabe hat die folgende Form, mit Semikolon als Zeilentrennzeichen und Kommas oder Leerzeichen als Spaltentrennzeichen in jeder Zeile:

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

Probieren Sie es online!

Erläuterung

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

Gearbeitetes Beispiel

Betrachten Sie die Eingabe [1 2 3; 4 5 6] . Die for-Schleife, die mit beginnt, "übernimmt jede Spalte der Eingabe. @Verschiebt die aktuelle Spalte innerhalb jeder Iteration auf den Stapel. Also drückt es in der ersten Iteration [1; 4]. N$Gibt an, dass der gesamte Stapelinhalt als Eingabe für die folgende Funktion verwendet wird.Yd .

Diese Funktion (die MATLABs entspricht blkdiag) "verknüpft" ihre Eingaben diagonal, um eine Blockdiagonalmatrix (2D-Array) zu erzeugen. Also in der ersten Iteration Ydnimmt es eine Eingabe und erzeugt eine Ausgabe gleich dieser Eingabe,[1; 4] , die auf dem Stapel verbleibt.

In der zweiten Iteration wird die zweite Spalte der Eingabe [2; 5]gedrückt. JetztYd zwei 2 × 1-Eingänge, nämlich [1; 4]und [2; 5], und erzeugt das 4 × 2-Array[1 0; 4 0; 0 2; 0 5] .

Bei der dritten Iteration werden Yddas letztere 4 × 2-Array und die dritte Spalte der Eingabe verwendet [3; 6]und das Endergebnis erzeugt [1 0 0; 4 0 0; 0 2 0; 0 5 0; 0 0 3; 0 0 6].

Luis Mendo
quelle
3

ES6, 65 Bytes

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

Nimmt als Eingabe und gibt als Ausgabe ein Array von Arrays zurück.

Neil
quelle
1
@WashingtonGuedes Die innere Karte gibt eine Kopie des ursprünglichen 2D-Arrays mit allen bis auf eine Spalte auf Null zurück. Diese Kopien müssen dann verkettet werden, anstatt nur Elemente eines äußeren 3D-Arrays zu sein.
Neil
3

Mathematica, 40 39 Bytes

Gutschrift an @Seeq für InfixingFlatten .

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

Die Eingabe ist eine Liste von Zeilenvektoren, die durch begrenzt sind {} Klammern . Das erste Beispiel ist also dargestellt durch

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

Generieren Sie ein Array DiagonalMatrixmit diagonalen Elementen aus den Zeilen der Eingabe (3-D-Array). TransposeDie FlattenOperation entfernt also die richtigen Klammernpaare, um die gewünschte Matrix (jetzt 2D-Array) zu erhalten.

IPoiler
quelle
1
Würde nicht DiagonalMatrix/@#funktionieren Und im weiteren Transpose[DiagonalMatrix/@#]~Flatten~1&
Sinne
Guter Fang, ich wollte das beheben, nachdem ich es aufgerollt hatte. Ich habe nicht daran gedacht, das zu nutzen Infix Flatten. +1.
IPoiler
2

Pyth, 17

s.em.>+dm0thQkbCQ

Probieren Sie es online aus oder starten Sie das Test Suite aus .

Sie können ein Lead hinzufügen j, um das 2D-Array besser zu visualisieren.

FryAmTheEggman
quelle
1

Jelly, 13 Bytes

ZLR’×L0ẋ;"Zz0

Probieren Sie es online!

Wie es funktioniert

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.
Dennis
quelle
1

Mathematica, 111 Bytes

Join@@@ReplacePart[Table[0,#2/#3]~Table~#3~Table~#3,Table[{n,n}->#[[n]],{n,#3}]]&[Length@#,Length@Flatten@#,#]&
CalculatorFeline
quelle
Was ist die Eingabesyntax? Dies wirft Tableund PartFehler bei der Standard - MMA Matrixnotation und die Ergebnisse in einer Reihe von Misch Dimensionen verwenden.
IPoiler
1

Ruby, 81 78 76 62 Bytes

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

Seufzer Manuelles Verfolgen des Index ist kürzer als 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
Türknauf
quelle
1

R, 41 Bytes

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

Angenommen pryr, Matrixundplyr Pakete sind installiert.

Dadurch wird eine Funktion erstellt, die ein 2D-Array (a) annimmt und eine "sparseMatrix" zurückgibt, wobei (wobei die Nullen als dargestellt werden .).

(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

Erläuterung:

plyr::alply(a,2)Jede Spalte von aund gibt diese Ergebnisse in einer Liste wieder

Matrix::.bdiag(lst) Erstellt eine Blockdiagonalmatrix aus einer Liste von Matrizen

pryr::f ist eine Kurzform zum Erstellen einer Funktion.

Eine vollständig Rbasierende Lösung in 59 Bytes (unter Verwendung der Logik der Matlab-Antwort von @ PieCot):

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

MATLAB, 69 68 Bytes

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

Ein Byte wurde abgeschabt: dank Luis Mendo :)

PieCot
quelle