Блочно-диагональная матрица из столбцов


16

Вдохновлено Скопировано из этого вопроса в Stack Overflow.

Учитывая матрицу A, создайте матрицу Bтак, чтобы столбцы Aбыли расположены по диагонали блоков. Например, учитывая

1 2 3
4 5 6

выход будет

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

правила

Вход и выход могут быть в форме 2D-массивов, вложенных массивов или строк с различными разделителями для строк и столбцов.

Числа на входе (матрица A) будут положительными целыми числами.

Разрешен унарный формат, если нули в выводе отображаются каким-либо разумным способом. Например, приведенный выше результат может отображаться с использованием кавычек для включения каждого числа:

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

Контрольные примеры

Ввод, вывод:

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

Будут ли все числа в A отличаться?
Адам

@ Nᴮᶻ Нет, они могут быть равны
Луис Мендо

Ответы:


7

MATL , 6 байтов

"@N$Yd

Работает в текущей версии (13.0.0) языка / компилятора.

Ввод имеет следующую форму с точкой с запятой в качестве разделителя строк и запятыми или пробелами в качестве разделителей столбцов в каждой строке:

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

Попробуйте онлайн!

объяснение

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

Работал пример

Рассмотрим вход [1 2 3; 4 5 6]. Цикл for начинается с "каждого столбца ввода. В каждой итерации @помещает текущий столбец в стек. Так что в первой итерации это толкает [1; 4]. N$указывает, что все содержимое стека будет использоваться в качестве входных данных для следующей функции Yd.

Эта функция (соответствующая MATLAB blkdiag) «объединяет по диагонали» свои входы, чтобы получить блочную диагональную матрицу (2D-массив). Таким образом, в первой итерации Ydон принимает один вход и производит выход, равный этому входу [1; 4], который остается в стеке.

Во второй итерации второй столбец ввода, [2; 5]вставляется. Теперь Ydпринимает два 2 × 1 входы, а именно [1; 4]и [2; 5], и производит массив с 4 × 2 [1 0; 4 0; 0 2; 0 5].

На третьей итерации Ydберется последний массив 4 × 2 и третий столбец ввода [3; 6], и выдается окончательный результат [1 0 0; 4 0 0; 0 2 0; 0 5 0; 0 0 3; 0 0 6].


3

ES6, 65 байт

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

Принимает в качестве входных данных и возвращает в качестве выходных данных массив массивов.


1
@WashingtonGuedes Внутренняя карта возвращает копию исходного двумерного массива со всеми, кроме одного, обнуленными столбцами. Эти копии затем должны быть объединены, а не просто являются элементами внешнего трехмерного массива.
Нил

3

Mathematica, 40 39 байт

Кредит @Seeq для Infixing Flatten.

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

Ввод - это список векторов строк, разделенных {}скобками. Таким образом, первоначальный пример представлен

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

Создайте массив, в DiagonalMatrixкотором каждый имеет диагональные элементы из строк ввода (трехмерный массив). Transposeпоэтому Flattenоперация удаляет правильные пары скобок, чтобы получить желаемую матрицу (теперь двумерный массив).


1
Не DiagonalMatrix/@#сработает? И, как следствие,Transpose[DiagonalMatrix/@#]~Flatten~1&
seequ

Хороший улов, я намеревался исправить это после сворачивания. Не думал использовать Infix Flattenхотя. +1.
IPoiler


1

Желе, 13 байт

ZLR’×L0ẋ;"Zz0

Попробуйте онлайн!

Как это устроено

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 байт

Join@@@ReplacePart[Table[0,#2/#3]~Table~#3~Table~#3,Table[{n,n}->#[[n]],{n,#3}]]&[Length@#,Length@Flatten@#,#]&

Какой синтаксис ввода? Это бросает Tableи Partошибки при использовании стандартных ММЫ матричных обозначений и результатов в массиве смешанных размеров.
IPoiler

1

Рубин, 81 78 76 62 байта

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

вздох Вручную отслеживание индекса короче, чем 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 байт

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

Предполагается pryr, Matrixи plyrпакеты установлены.

Это создает функцию, которая принимает 2D-массив (a) и возвращает «sparseMatrix», где (где 0 представлены как .)

(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

Объяснение:

plyr::alply(a,2)каждый столбец aи возвращает объединяет эти результаты в список

Matrix::.bdiag(lst) создает диагональную матрицу блока из списка матриц

pryr::f это сокращенный способ создания функции.

Полностью базовое Rрешение в 59 байт (используя логику ответа Matlab @ PieCot):

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

1

MATLAB, 69 68 байт

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

Один байт сбрили: спасибо Луису Мендо :)


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.