Blokowa diagonalna macierz z kolumn

16

Zainspirowany przez skopiowane z tego pytania w Stack Overflow.

Biorąc pod uwagę matrycę A, utwórz matrycę w Btaki sposób, aby kolumny Abyły ułożone blokowo po przekątnej. Na przykład dane

1 2 3
4 5 6

wynik byłby

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

Zasady

Dane wejściowe i wyjściowe mogą być w postaci tablic 2D, tablic zagnieżdżonych lub łańcuchów z różnymi separatorami dla wierszy i kolumn.

Liczby na wejściu (macierz A ) będą dodatnimi liczbami całkowitymi.

Dowolny format jest dozwolony, o ile zera są wyświetlane w jakiś rozsądny sposób. Na przykład powyższy wynik można wyświetlić za pomocą znaków cudzysłowu w celu dołączenia każdej liczby:

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

Przypadki testowe

Wejście wyjście:

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
źródło
Czy wszystkie liczby w A będą inne?
Adám
@ Nᴮᶻ Nie, mogą być równi
Luis Mendo,

Odpowiedzi:

7

MATL , 6 bajtów

"@N$Yd

Pracuje w bieżącej wersji (13.0.0) języka / kompilatora.

Dane wejściowe mają następującą postać, z średnikiem jako separatorem wierszy, a przecinki lub spacje jako separatory kolumn w każdym wierszu:

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

Wypróbuj online!

Wyjaśnienie

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

Przykład działał

Rozważ dane wejściowe [1 2 3; 4 5 6]. Pętla for rozpoczynająca się od "zajmuje każdą kolumnę danych wejściowych. W ramach każdej iteracji @wypycha bieżącą kolumnę na stos. Więc w pierwszej iteracji popycha [1; 4]. N$określa, że ​​cała zawartość stosu będzie używana jako dane wejściowe następującej funkcji,Yd .

Ta funkcja (odpowiadająca MATLAB-owi blkdiag) „łączy diagonalnie” swoje dane wejściowe, aby utworzyć blokową macierz diagonalną (macierz 2D). Tak więc w pierwszej iteracji Ydpobiera jedno wejście i tworzy wynik równy temu wejściu,[1; 4] , który pozostawia na stosie.

W drugiej iteracji [2; 5]wypychana jest druga kolumna danych wejściowych . Teraz Ydpobiera dwa wejścia 2 × 1, mianowicie [1; 4]i [2; 5], i tworzy tablicę 4 × 2 [1 0; 4 0; 0 2; 0 5].

W trzeciej iteracji Ydbierze ostatnią tablicę 4 × 2 i trzecią kolumnę danych wejściowych [3; 6]i daje wynik końcowy [1 0 0; 4 0 0; 0 2 0; 0 5 0; 0 0 3; 0 0 6].

Luis Mendo
źródło
3

ES6, 65 bajtów

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

Pobiera jako dane wejściowe i zwraca jako dane wyjściowe tablicę tablic.

Neil
źródło
1
@WashingtonGuedes Mapa wewnętrzna zwraca kopię oryginalnej tablicy 2D z wyzerowanymi wszystkimi kolumnami oprócz jednej. Kopie te należy następnie połączyć, a nie tylko elementy zewnętrznej tablicy 3D.
Neil
3

Mathematica, 40 39 bajtów

Podziękowania dla @Seeq za Infixing Flatten.

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

Dane wejściowe to lista wektorów wierszy oddzielonych {}nawiasami. Tak więc początkowy przykład jest reprezentowany przez

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

Wygeneruj tablicę, w DiagonalMatrixktórej każdy ma elementy ukośne z rzędów wejściowych (tablica 3-W). Transposewięc Flattenoperacja usuwa prawidłowe pary nawiasów, aby uzyskać żądaną macierz (teraz tablica 2-D).

IPoiler
źródło
1
Nie DiagonalMatrix/@#działałoby? A przez rozszerzenieTranspose[DiagonalMatrix/@#]~Flatten~1&
patrz
Dobry haczyk, chciałem to naprawić po zwinięciu. Nie myślałem Infix Flattenjednak o tym. +1.
IPoiler
2

Pyth, 17 lat

s.em.>+dm0thQkbCQ

Wypróbuj online lub uruchom pakiet testowy .

Możesz dodać wiodącą jpomoc w wizualizacji tablicy 2D.

FryAmTheEggman
źródło
1

Galaretka, 13 bajtów

ZLR’×L0ẋ;"Zz0

Wypróbuj online!

Jak to działa

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
źródło
1

Mathematica, 111 bajtów

Join@@@ReplacePart[Table[0,#2/#3]~Table~#3~Table~#3,Table[{n,n}->#[[n]],{n,#3}]]&[Length@#,Length@Flatten@#,#]&
CalculatorFeline
źródło
Jaka jest składnia wejściowa? To generuje Tablei Partbłędów przy użyciu standardowego zapisu matrycy MMA i powoduje szereg mieszanych wymiarach.
IPoiler
1

Ruby, 81 78 76 62 bajtów

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

westchnienie Ręczne śledzenie indeksu jest krótsze niż 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
Klamka
źródło
1

R, 41 bajtów

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

Zakłada się pryr, Matrixi plyrsą zainstalowane pakiety.

Tworzy to funkcję, która pobiera tablicę 2D (a) i zwraca „sparseMatrix”, gdzie (gdzie 0 jest reprezentowane jako .)

(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

Wyjaśnienie:

plyr::alply(a,2) każda kolumna a i zwraca łączy wyniki na liście

Matrix::.bdiag(lst) tworzy blokową macierz diagonalną z listy macierzy

pryr::f to skrótowy sposób tworzenia funkcji.

W pełni podstawowe Rrozwiązanie w 59 bajtach (przy użyciu logiki odpowiedzi Matlab @ PieCot):

function(a){l=dim(a);diag(l[2])%x%matrix(1,nrow=l[1])*c(a)}
mnel
źródło
1

MATLAB, 69 68 bajtów

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

Ogolono jeden bajt: dzięki Luisowi Mendo :)

PieCot
źródło