Diamondize Матрица


20

Для данной матрицы выведите представление матрицы, в которой верхний левый элемент находится сверху, антидиагональный - это центральная строка, а нижний правый элемент - внизу.

Например, рассмотрим следующую матрицу:

1 2 3
4 5 6
7 8 9

Алмазная версия этой матрицы:

  1
 4 2
7 5 3
 8 6
  9

Входы и выходы

Матрица ввода будет представлена ​​в виде списка списков (или чего-либо подобного на выбранном вами языке). На выходе также должен быть список списков.

Матрицы будут содержать только натуральные числа.

Входная матрица не обязательно будет квадратной.

Входная матрица будет не менее 1 × 1.

Тестовые случаи

Input:  [[1]]
Output: [[1]]

Input:  [[1,2],[3,4]]
Output: [[1],[3,2],[4]]

Input:  [[1,2,3],[4,5,6]]
Output: [[1],[4,2],[5,3],[6]]

Input:  [[11,2,5],[3,99,3],[4,8,15],[16,23,42]]
Output: [[11],[3,2],[4,99,5],[16,8,3],[23,15],[42]]

счет

Это , поэтому выигрывает самый короткий ответ в байтах.



Связанное / обобщение. (Хотя это не было бы обманом, так как этот допускал рваные массивы и требовал поворота на любое кратное 45 градусов.)
Мартин Эндер,

Ответы:


19

J 7 байт

<@|./.

Это неназванный монадический глагол, который берет матрицу и возвращает список антидиагоналей:

   input =. i.3 4
   input
0 1  2  3
4 5  6  7
8 9 10 11

   <@|./. input
┌─┬───┬─────┬─────┬────┬──┐
│0│4 1│8 5 2│9 6 3│10 7│11│
└─┴───┴─────┴─────┴────┴──┘

Проверьте это здесь.

объяснение

  • /.является встроенным в J, чтобы применить функцию к каждой анти-диагонали. К сожалению, эти антидиагонали даны в порядке, обратном тому, что мы хотим здесь.
  • В <@|., мы сначала применить |.меняющий анти-диагонали , а затем <в поле его (это единственный способ вернуть рваный массив в J, так как обычные массивы всегда прямоугольные, так antidiagonals будет дополнен нулями).

Это безумие и красиво. Я найду время, чтобы выучить этот язык однажды.
машина тоскует

5

Python, 91 байт

e=enumerate
lambda M:[[r[n-i]for i,r in e(M)if-1<n-i<len(r)][::-1]for n,_ in e(M[1:]+M[0])]

Проверьте это на Ideone .


Python + NumPy, 69 байт

import numpy
lambda M:map(M[::-1].diagonal,range(1-len(M),len(M[0])))

Ожидает двумерный массив NumPy в качестве входных данных и возвращает список массивов NumPy. Проверьте это на Ideone .


4

Желе, 7 байт

ṚŒDṙZL$

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

объяснение

Ṛ         Reverse the matrix vertically.
 ŒD       Get its diagonals. However these start from 
          the main diagonal, not the corners.
    ZL$   Get the width of the input matrix.
   ṙ      Rotate the list of diagonals left by that many 
          places to obtain the correct order.

Не знаю Jelly, но это не 7 байт, если для этого требуются юникодные операнды.
Guidobot

5
@Guidobot Jelly использует пользовательскую кодовую страницу, которая кодирует каждый из 256 символов, которые он понимает как один байт.
Деннис

4

Mathematica, 58 56 байт

a=Length;Reverse@#~Diagonal~b~Table~{b,1-a@#,a@#&@@#-1}&

Анонимная функция, принимает вложенные массивы.


Вы можете сохранить один, Length[#]где есть \[Transpose]. И, вероятно, еще один из псевдонимов Length.
Sp3000

Или Length@#&@@#для ASCII только при том же количестве байтов.
Мартин Эндер

3

CJam, 17 байт

{eeSf.*::+W%zSf-}

Безымянный блок (функция), который ожидает матрицу в стеке и заменяет ее своими антидиагоналами.

Проверьте это здесь.

Это (найдено Sp3000) работает с тем же количеством байтов:

{_,,Sf*\.+W%zSf-}

объяснение

Это лучше всего объяснить на примере. Рассмотрим вход:

[[0  1  2  3]
 [4  5  6  7]
 [8  9 10 11]]

ee    e# Enumerate matrix, turning each row [x ... z] into [i [x ... z]] where
      e# i is the vertical index from the top.

[[0 [0  1  2  3]]
 [1 [4  5  6  7]]
 [2 [8  9 10 11]]]

Sf.*  e# Replace each i with a string of i spaces.

[[""   [0  1  2  3]]
 [" "  [4  5  6  7]]
 ["  " [8  9 10 11]]]

::+   e# Prepend these strings to the rows.

[[0  1  2  3]
 ['  4  5  6  7]
 ['  '  8  9 10 11]]   e# Note that each '  corresponds to a space character.

W%    e# Reverse the rows.

[['  '  8  9 10 11]
 ['  4  5  6  7]
 [0  1  2  3]]

z     e# Zip/transpose.

[[ '  '  0]
 [ '  4  1]
 [ 8  5  2]
 [ 9  6  3]
 [10  7]
 [11]]

Sf-   e# Remove spaces from each row.

[[ 0]
 [ 4  1]
 [ 8  5  2]
 [ 9  6  3]
 [10  7]
 [11]]

3

Python 2, 88 87 байт

lambda L:[filter(None,x)[::-1]for x in map(None,[],*[i*[0]+r for i,r in enumerate(L)])]

Предварительно добавьте 0s, zip, затем удалите ложные элементы. Возвращает список кортежей. Это используется map(None,...)для выполнения zip_longest (заполнение недостающими пятнами None) и filter(None,...)для удаления ложных элементов.

Досадно, что нам нужно добавить в []строку дополнительную строку, чтобы mapгарантировать возвращение списка кортежей, поскольку map(None,*[[1]])возвращается, [1]а не [(1,)]для матрицы 1x1. filterХотя лишний ряд удаляется .

(Спасибо @Dennis за -1 байт)


3

Рубин, 68 66 байт

Анонимная функция.

->l{i=-1;k=[];l.map{|r|i-=j=-1;r.map{|e|k[i+j+=1]=[e,*k[i+j]]}};k}
  • Благодаря тому, как работает оператор splat, я смог сэкономить 2 байта, отказавшись от добавления массива.

2

Mathematica, 60 байт

#&@@@#&/@GatherBy[Join@@MapIndexed[List,#,{2}],Tr@*Last]&

где символ Unicode, который Mathematica читает как постфиксный \[Transpose]оператор.

Это немного дольше, чем другое решение Mathematica, но я решил опубликовать его, потому что оно не использует Diagonalsвстроенный и использует совершенно другой подход.

объяснение

MapIndexed[List,#,{2}]

Это сначала транспонирует матрицу (так, чтобы антидиагоналы появлялись в правильном порядке, если матрица была уплощена). Затем мы отображаем Listячейки матрицы вместе с индексом, который превращает каждый элемент матрицы iв {i, {x, y}}где xи yявляются координатами элемента в матрице.

Join@@...

Это выравнивает самое внешнее измерение, так что теперь у нас есть плоский список матричных элементов (с их координатами) в главном порядке столбцов.

GatherBy[..., Tr@*Last]

Это группирует эти элементы по сумме их координат. Обратите внимание, что антидиагоналы являются линиями констант x+y, так что это именно та группировка, которую мы хотим. Порядок в каждой группе сохраняется. Теперь нам просто нужно снова избавиться от координат. Это делается с помощью довольно загадочного:

#&@@@#&/@...

Это отображает функцию #&@@@#&на каждую группу, которая сама применяется #& к каждому элементу в группе и #является просто первым аргументом, то есть исходным матричным элементом.


Любое объяснение почему читается как \[transpose]?
Fatalize

1
@Fatalize Это кодовая точка Unicode для частного использования, и глиф, который Mathematica ассоциирует с этой кодовой точкой, представляет собой верхний индекс T: reference.wolfram.com/language/ref/character/Transpose.html ... \[Transpose]просто транслитерация ASCII этого символа Unicode. Копирование символа Unicode или транслитерации в Mathematica будет работать.
Мартин Эндер

2

Октава, 77 байт

С небольшим злоупотреблением accumarrayфункцией:

@(M)char(accumarray(((1:size(M,1))+(0:size(M,2)-1)')(:),M(:),[],@(x){num2str(x')}))

Это определяет анонимную функцию. Чтобы использовать его, присвойте переменную или используйте ans.

Ввод - это матрица с :разделителем строк. Выход - это массив ячеек, содержащий массив для каждой строки (октавный эквивалент для зубчатых массивов). Это отображается в Octave с указанием индексов массива ячеек и содержимого каждой ячейки. Попробуй это здесь .

Для отображения результата, разделенного только пробелами и символами новой строки: 83 байта

@(M)char(accumarray(((1:size(M,1))+(0:size(M,2)-1)')(:),M(:),[],@(x){num2str(x')}))

Вы также можете попробовать это здесь .


2

JavaScript (Firefox), 86 75 байт

a=>a.concat(a[0]).slice(1).map((_,i)=>[for(v of a)if(n=v[i--])n].reverse())

Сохранено 11 байтов благодаря @Neil!

Работает в Firefox 30+. Принимает массив массивов.


Хороший алгоритм, но вы можете использовать, a.concat(a[0]).slice(1)чтобы получить массив правильной длины. Кроме того, [for(of)]это не ES6; Я обычно пишу это как (Firefox 30+) или что-то подобное.
Нил

@ Нил Вау, я чувствую себя немного глупо, не решив использовать concatи slice. Благодарность!
user81655

2

Октава, 63 62 байта

Удалил один байт благодаря @DonMue ... @LuisMendo!

@(a)cellfun(@(x)x(x>0)',num2cell(spdiags(flipud(a)),1),'un',0)

Я пошел по скучному маршруту и ​​проглотил антидиагоналы.

Пробный прогон на идеоне .


Я думаю , что вы можете сократить 'uni'до'un'
Луис Mendo

@ LuisMendo Почему, да, я могу! Благодарность! :)
стакан

2

Haskell, 83 82 байта

r=zip[0..]
\o->fst$span(any(>0))[reverse[e|(x,t)<-r o,(v,e)<-r t,x+v==a]|a<-[0..]]

Ними спасла байт. Благодарность!


1

Python, 128 байт (numpy)

(lambda A: (lambda A,S:[[A[U][I-U] for U in range(min(S[1]-1,I),max(I-S[0]+1,0)-1,-1)] for I in range(S[1]+S[0]-1)])(A,A.shape))

Добро пожаловать в Программирование Пазлов и Code Golf! По умолчанию представления кода Code Gallenge должны быть программами или функциями и использовать один из утвержденных методов ввода / вывода . Фрагмент, который ожидает ввода в жестко закодированной переменной, не допускается.
Деннис

Похоже, вы можете переделать первое решение, которое использует lambdaпросто лямбду, которую вы можете использовать в качестве представления.
Алекс А.

Я буду лямбда это
Луис Масуэлли

lambda A:[[A[U][I-U]for U in range(max(I-len(A)+1,0),min(len(A[0])-1,I)+1)]for I in range(len(A+A[0])-1)](как в вашей первоначальной ревизии) будет немного короче. Кроме того, вы должны перейти A[U][I-U]к, A[I-U][U]чтобы получить ориентацию из вопроса.
Деннис

Я проверю это, когда вернусь домой. Имеет смысл
Луис Масуэлли

1

Pyth , 41 17 байт

tm_<dx+dYk.T+LaYk

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

Вдохновленный решением @ Doorknob другой проблемы .

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

tm_<dx+dYk.T+LaYk
            +L      prepend to each subarray...
              aYk   (Y += ''). Y is initialized to [],
                    so this prepends [''] to the first
                    subarray, ['', ''] to the second, etc.
                    ['' 1  2  3
                     '' '' 4  5  6
                     '' '' '' 7  8  9
                     '' '' '' '' 10 11 12
                     '' '' '' '' '' 13 14 15]
          .T        transpose, giving us
                    ['' '' '' '' ''
                     1  '' '' '' ''
                     2  4  '' '' ''
                     3  5  7  '' ''
                     6  8  10 ''
                     9  11 13
                     12 14
                     15]
 m_<dx+dYk          removes all empty strings in the
                    subarrays while reversing each one
t                   remove the first subarray

Предыдущая попытка:

JlQKlhQm_m@@Qk-dk}h.MZ,0-dtKh.mb,tJdUt+JK

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

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

JlQKlhQm_m@@Qk-dk}h.MZ,0-dtKh.mb,tJdUt+JK    input array stored as Q
JlQ                                          J = len(Q)
   KlhQ                                      K = len(Q[0])
       m                            Ut+JK    list for d from 0 to J+K-1:
        _m       }AAAAAAAAAABBBBBBBB             reversed list for k from A to B, where:
                  h.MZ,0-dtK                       A = max(0, d-(K-1))
                       0-dtK                               0  d-(K-1)
                            h.mb,tJd               B = min(J-1, d)
                                 tJd                       J-1  d
          @@Qk-dk                                    Q[k][d-k]

1

Groovy, 77 73 75

{i->o=[].withDefault{[]};a=0;i.each{b=0;it.each{o[a+b++].add(0,it)};a++};o}

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

Попытайся

РЕДАКТИРОВАТЬ: я забыл вывести anwser, после добавления его оценка достигает 75.

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