Діамантуйте матрицю


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

Пітон, 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])))

Очікує 2D масив 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 байт, якщо для нього потрібні операнди unicode.
Гідобот

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

4

Математика, 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, застебніть, а потім видаліть фальшиві елементи. Повертає список кортежів. Це використовується 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

Математика, 60 байт

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

де символ Unicode, який Mathematica читає як \[Transpose]оператор postfix .

Це трохи довше, ніж інше рішення Mathematica, але я подумав, що опублікую його, оскільки він не використовує Diagonalsвбудований і використовує зовсім інший підхід.

Пояснення

MapIndexed[List,#,{2}]

Це спочатку переміщує матрицю (так, що антидіагоналі з'являються у правильному порядку, якщо матриця була сплющена). Потім ми наносимо Listна карту матриці разом з індексом, який перетворює кожен елемент матриці iна те, {i, {x, y}}де xі yє координати елемента в матриці.

Join@@...

Це згладжує самий зовнішній вимір, так що тепер ми маємо плоский перелік елементів матриці (з їх координатами) у порядку основного стовпця.

GatherBy[..., Tr@*Last]

Він групує ці елементи за сумою їх координат. Зауважимо, що антидіагоналі є лініями постійними x+y, тому це точно відповідає групуванню, яке ми хочемо. Порядок в межах кожної групи зберігається. Тепер нам просто потрібно знову позбутися координат. Це робиться через досить криптовалюту:

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

Це відображає функцію #&@@@#&над кожною групою, яка сама застосовується #& до кожного елемента в групі, і #є просто першим аргументом, тобто початковим матричним елементом.


Будь-яке пояснення, чому читається як \[transpose]?
Фаталізувати

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 до зубчастих масивів). Це відображається 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+) або щось подібне.
Ніл

@Neil Вау, я відчуваю себе трохи нерозумно, не зрозумівши, що використовувати concatі slice. Спасибі!
користувач81655

2

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

Видалений один байт завдяки @DonMue ... @LuisMendo!

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

Я пішов нудним шляхом і заграв антидіагоналі.

Зразок запущений на ideone .


Я думаю, ви можете скоротити 'uni'до'un'
Луїс Мендо

@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))

Ласкаво просимо до головоломки програмування та коду для гольфу! За замовчуванням подання на код для виклику гольфу має бути програмами або функціями та використовувати один із затверджених методів вводу-виводу . Фрагмент, який очікує введення в твердо кодовану змінну, не дозволений.
Денніс

Схоже, ви можете переробити перше рішення, яке використовується 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

Гровий, 77 73 75

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

Приймає масив масивів як вхідний і повертає масив масивів.

Спробуй це

EDIT: Я забув вивести низький показник, після додавання його оцінка піднімається до 75.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.