Matrice bloc-diagonale des colonnes

16

Inspiré de Copied from this question at Stack Overflow.

Étant donné une matrice A, créez une matrice Btelle que les colonnes de Asoient disposées en diagonale de bloc. Par exemple, étant donné

1 2 3
4 5 6

la sortie serait

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

Règles

L'entrée et la sortie peuvent prendre la forme de tableaux 2D, de tableaux imbriqués ou de chaînes avec des séparateurs différents pour les lignes et les colonnes.

Les nombres dans l'entrée (matrice A) seront des entiers positifs.

Le format unaire est autorisé, tant que les zéros dans la sortie sont affichés d'une manière raisonnable. Par exemple, le résultat ci-dessus peut être affiché à l'aide de guillemets pour entourer chaque numéro:

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

Cas de test

Entrée sortie:

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
la source
Est-ce que tous les nombres en A seront différents?
Adám
@ Nᴮᶻ Non, ils peuvent être égaux
Luis Mendo

Réponses:

7

MATL , 6 octets

"@N$Yd

Fonctionne dans la version actuelle (13.0.0) du langage / compilateur.

L'entrée a la forme suivante, avec un point-virgule comme séparateur de ligne et des virgules ou des espaces comme séparateurs de colonne dans chaque ligne:

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

Essayez-le en ligne!

Explication

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

Exemple travaillé

Considérez l'entrée [1 2 3; 4 5 6]. La boucle for commençant par "prend chaque colonne de l'entrée. Dans chaque itération, @pousse la colonne actuelle sur la pile. Donc dans la première itération ça pousse [1; 4]. N$précise que tout le contenu de la pile seront utilisés comme entrées de la fonction suivante, Yd.

Cette fonction (correspondant à MATLAB blkdiag) "concatène diagonalement" ses entrées pour produire une matrice diagonale de bloc (tableau 2D). Donc, dans la première itération, Ydil prend une entrée et produit une sortie égale à cette entrée [1; 4], qui est laissée sur la pile.

Dans la deuxième itération, la deuxième colonne de l'entrée [2; 5],, est poussée. Prend maintenant Yddeux entrées 2 × 1, à savoir [1; 4]et [2; 5], et produit le tableau 4 × 2 [1 0; 4 0; 0 2; 0 5].

Dans la troisième itération Ydprend le dernier tableau 4 × 2 et la troisième colonne de l'entrée [3; 6], et produit le résultat final [1 0 0; 4 0 0; 0 2 0; 0 5 0; 0 0 3; 0 0 6].

Luis Mendo
la source
3

ES6, 65 octets

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

Prend en entrée et renvoie en sortie un tableau de tableaux.

Neil
la source
1
@WashingtonGuedes La carte interne renvoie une copie du tableau 2D d'origine avec toutes les colonnes sauf une mises à zéro. Ces copies doivent ensuite être concaténées, plutôt que d'être simplement des éléments d'un réseau 3D externe.
Neil
3

Mathematica, 40 39 octets

Crédit à @Seeq pour Infixing Flatten.

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

L'entrée est une liste de vecteurs de ligne délimités par des {}crochets. Ainsi, l'exemple initial est représenté par

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

Générez un tableau DiagonalMatrixoù chacun a des éléments diagonaux à partir des lignes de l'entrée (tableau 3-D). Transposede sorte que l' Flattenopération supprime les paires de parenthèses correctes pour donner la matrice souhaitée (désormais tableau 2D).

IPoiler
la source
1
Ça ne DiagonalMatrix/@#marcherait pas ? Et, par extension,Transpose[DiagonalMatrix/@#]~Flatten~1&
voir le
Bonne prise, j'avais l'intention de réparer ça après l'avoir roulé. Je n'ai pas pensé à utiliser le Infix Flattenbien. +1.
IPoiler
2

Pyth, 17

s.em.>+dm0thQkbCQ

Essayez-le en ligne ou exécutez la suite de tests .

Vous pouvez ajouter un interligne jpour aider à visualiser le tableau 2D.

FryAmTheEggman
la source
1

Gelée, 13 octets

ZLR’×L0ẋ;"Zz0

Essayez-le en ligne!

Comment ça fonctionne

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
la source
1

Mathematica, 111 octets

Join@@@ReplacePart[Table[0,#2/#3]~Table~#3~Table~#3,Table[{n,n}->#[[n]],{n,#3}]]&[Length@#,Length@Flatten@#,#]&
CalculatorFeline
la source
Quelle est la syntaxe d'entrée? Cela jette Tableet des Parterreurs lors de l' utilisation de la notation matrice standard MMA et les résultats dans un tableau de dimensions mixtes.
IPoiler
1

Rubis, 81 78 76 62 octets

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

soupir Le suivi manuel de l'indice est plus court que 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
Poignée de porte
la source
1

R, 41 octets

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

Suppose pryr, Matrixet les plyrpaquets sont installés.

Cela crée une fonction qui prend un tableau 2D (a) et renvoie un "sparseMatrix" où (où les 0 sont représentés comme .)

(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

Explication:

plyr::alply(a,2)chaque colonne aet retours combine ces résultats dans une liste

Matrix::.bdiag(lst) crée une matrice diagonale de bloc à partir d'une liste de matrices

pryr::f est un raccourci pour créer une fonction.

Une Rsolution de base complète en 59 octets (utilisant la logique de la réponse Matlab de @ PieCot):

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

MATLAB, 69 68 octets

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

Un octet a été rasé: grâce à Luis Mendo :)

PieCot
la source