Matriz diagonal de bloco de colunas

16

Inspirado por Copiado desta pergunta no Stack Overflow.

Dada uma matriz A, crie uma matriz de Bmodo que as colunas de Asejam dispostas na diagonal do bloco. Por exemplo, dado

1 2 3
4 5 6

a saída seria

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

Regras

A entrada e a saída podem estar na forma de matrizes 2D, matrizes aninhadas ou seqüências de caracteres com diferentes separadores para linhas e colunas.

Os números na entrada (matriz A) serão números inteiros positivos.

O formato unário é permitido, desde que os zeros na saída sejam exibidos de uma maneira razoável. Por exemplo, o resultado acima pode ser exibido usando aspas para incluir cada número:

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

Casos de teste

Entrada, saída:

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
fonte
Todos os números em A serão diferentes?
Adám
@ Nᴮᶻ Não, eles podem ser igual
Luis Mendo

Respostas:

7

MATL , 6 bytes

"@N$Yd

Funciona na versão atual (13.0.0) do idioma / compilador.

A entrada possui o seguinte formato, com ponto-e-vírgula como separador de linhas e vírgulas ou espaços como separadores de colunas em cada linha:

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

Experimente online!

Explicação

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

Exemplo trabalhado

Considere a entrada [1 2 3; 4 5 6]. O loop for começando com "leva cada coluna da entrada. Dentro de cada iteração, @empurra a coluna atual para a pilha. Então, na primeira iteração, ele empurra [1; 4]. N$especifica que todo o conteúdo da pilha será usado como entrada da seguinte função Yd,.

Esta função (correspondente ao MATLAB blkdiag) "concatena diagonalmente" suas entradas para produzir uma matriz diagonal de bloco (matriz 2D). Portanto, na primeira iteração, Ydé necessária uma entrada e produz uma saída igual a essa entrada [1; 4], que é deixada na pilha.

Na segunda iteração, a segunda coluna da entrada [2; 5],, é pressionada. Agora Ydtem duas entradas de 2 × 1, nomeadamente [1; 4]e [2; 5], e produz a matriz 4 × 2 [1 0; 4 0; 0 2; 0 5].

Na terceira iteração, Ydpega a última matriz 4 × 2 e a terceira coluna da entrada [3; 6]e produz o resultado final [1 0 0; 4 0 0; 0 2 0; 0 5 0; 0 0 3; 0 0 6].

Luis Mendo
fonte
3

ES6, 65 bytes

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

Toma como entrada e retorna como saída uma matriz de matrizes.

Neil
fonte
1
@WashingtonGuedes O mapa interno retorna uma cópia da matriz 2D original com todas menos uma coluna zerada. Essas cópias precisam ser concatenadas, em vez de apenas serem elementos de uma matriz 3D externa.
Neil
3

Mathematica, 40 39 Bytes

Crédito para @Seeq por Infixing Flatten.

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

Entrada é uma lista de vetores de linha delimitados por {}colchetes. Portanto, o exemplo inicial é representado por

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

Gere uma matriz de DiagonalMatrixonde cada uma possui elementos diagonais das linhas da entrada (matriz 3-D). Transposeportanto, a Flattenoperação remove os pares de colchetes corretos para fornecer a matriz desejada (agora matriz 2-D).

IPoiler
fonte
1
Não DiagonalMatrix/@#funcionaria? E, por extensão,Transpose[DiagonalMatrix/@#]~Flatten~1&
23/02
Boa captura, pretendia consertar isso depois de enrolá-lo. Não pensou em usar o pensamento Infix Flatten. +1.
IPoiler
2

Pyth, 17

s.em.>+dm0thQkbCQ

Experimente online ou execute o Test Suite .

Você pode adicionar um líder jpara ajudar a visualizar a matriz 2D.

FryAmTheEggman
fonte
1

Gelatina, 13 bytes

ZLR’×L0ẋ;"Zz0

Experimente online!

Como funciona

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
fonte
1

Mathematica, 111 bytes

Join@@@ReplacePart[Table[0,#2/#3]~Table~#3~Table~#3,Table[{n,n}->#[[n]],{n,#3}]]&[Length@#,Length@Flatten@#,#]&
CalculatorFeline
fonte
Qual é a sintaxe de entrada? Esta lança Tablee Parterros quando usando a notação de matriz de MMA padrão e os resultados em uma matriz de dimensões mistas.
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}}}

suspiro Manter o controle manual do índice é menor 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
Maçaneta
fonte
1

R, 41 bytes

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

Assume pryr,Matrix e plyrpacotes são instalados.

Isso cria uma função que pega uma matriz 2D (a) e retorna uma "sparseMatrix" onde (onde 0's são representados como .)

(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

Explicação:

plyr::alply(a,2)cada coluna de ae retorna combina esses resultados em uma lista

Matrix::.bdiag(lst) cria uma matriz diagonal de bloco a partir de uma lista de matrizes

pryr::f é uma maneira abreviada de criar uma função.

Uma Rsolução totalmente básica em 59 bytes (usando a lógica da resposta do Matlab do @ PieCot):

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

MATLAB, 69 68 bytes

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

Um byte foi eliminado: graças a Luis Mendo :)

PieCot
fonte