Diamondize a Matrix

20

Biorąc pod uwagę macierz, wyświetl reprezentację macierzy, w której górny lewy element znajduje się na górze, anty-przekątna jest środkowym rzędem, a prawy dolny element jest na dole.

Rozważmy na przykład następującą macierz:

1 2 3
4 5 6
7 8 9

Diamentowa wersja tej matrycy to:

  1
 4 2
7 5 3
 8 6
  9

Wejścia i wyjścia

Macierz wprowadzania zostanie podana jako lista list (lub cokolwiek podobnego w wybranym języku). Wynikiem powinna być również lista list.

Macierze będą zawierać tylko dodatnie liczby całkowite.

Macierz wejściowa niekoniecznie będzie kwadratowa.

Matryca wejściowa będzie wynosić co najmniej 1 × 1.

Przypadki testowe

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]]

Punktacja

To jest , więc wygrywa najkrótsza odpowiedź w bajtach.

Fatalizować
źródło
Powiązane
Fatalizuj
Powiązane / uogólnienie. (Nie uważałbym tego za oszustwo, ponieważ pozwalało to na poszarpane tablice i wymagało obrotu o dowolną wielokrotność 45 stopni.)
Martin Ender
Związane z.
Martin Ender,

Odpowiedzi:

19

J, 7 bajtów

<@|./.

Jest to bezimienny czasownik monadyczny, który pobiera macierz i zwraca listę antydiagonali:

   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│
└─┴───┴─────┴─────┴────┴──┘

Sprawdź to tutaj.

Wyjaśnienie

  • /.jest wbudowany w J, aby zastosować funkcję do każdej anty-przekątnej. Niestety, te anty-przekątne są podane w odwrotnej kolejności niż tutaj.
  • W <@|., najpierw zastosujemy, |.który odwraca anty-przekątną, a następnie <umieszcza ją w ramce (jest to jedyny sposób, aby zwrócić nierówną tablicę w J, ponieważ normalne tablice są zawsze prostokątne, więc antyiagonale byłyby wypełnione zerami).
Martin Ender
źródło
To jest szalone i piękne. Poświęcę trochę czasu na naukę tego języka.
maszyna tęskni
5

Python, 91 bajtów

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

Przetestuj na Ideone .


Python + NumPy, 69 bajtów

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

Oczekuje na wejście tablicy 2D NumPy i zwraca listę tablic NumPy. Przetestuj na Ideone .

Dennis
źródło
4

Galaretka, 7 bajtów

ṚŒDṙZL$

Wypróbuj online!

Wyjaśnienie

Ṛ         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.
Martin Ender
źródło
Nie znam Jelly, ale to nie jest 7 bajtów, jeśli wymaga operandów w standardzie Unicode.
Guidobot,
5
@Guidobot Jelly używa niestandardowej strony kodowej, która koduje każdy z 256 znaków, które rozumie jako pojedynczy bajt.
Dennis,
4

Mathematica, 58 56 bajtów

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

Funkcja anonimowa, przyjmuje zagnieżdżone tablice.

LegionMammal978
źródło
Możesz zapisać jedną z tym, Length[#]gdzie jest \[Transpose]. I prawdopodobnie kolejny z aliasingu Length.
Sp3000,
Lub Length@#&@@#dla ASCII tylko przy tej samej liczbie bajtów.
Martin Ender,
3

CJam, 17 bajtów

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

Nienazwany blok (funkcja), który oczekuje matrycy na stosie i zastępuje ją antydiagonalami.

Sprawdź to tutaj.

To (znalezione przez Sp3000) działa dla tej samej liczby bajtów:

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

Wyjaśnienie

Można to najlepiej wyjaśnić na przykładzie. Rozważ dane wejściowe:

[[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]]
Martin Ender
źródło
3

Python 2, 88 87 bajtów

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

Dodaj zera, zip, a następnie usuń elementy fałszowania. Zwraca listę krotek. Wykorzystuje map(None,...)do wykonywania zip_longest (dopełnienie brakujących plamy None) oraz filter(None,...)usunąć elementy falsy.

Irytująco musimy dodać dodatkowy []wiersz do, mapaby zagwarantować, że lista krotek zostanie zwrócona, ponieważ map(None,*[[1]])zwraca [1]raczej niż [(1,)]macierz 1x1. Dodatkowy rząd zostaje jednak usunięty filter.

(Dzięki @Dennis za -1 bajt)

Sp3000
źródło
3

Rubin, 68 66 bajtów

Funkcja anonimowa.

->l{i=-1;k=[];l.map{|r|i-=j=-1;r.map{|e|k[i+j+=1]=[e,*k[i+j]]}};k}
  • Z powodu tego, jak działa operator splat, byłem w stanie zaoszczędzić 2 bajty, rezygnując z dodawania tablicy.
Wartość tuszu
źródło
2

Mathematica, 60 bajtów

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

gdzie jest znakiem Unicode, który Mathematica odczytuje jako \[Transpose]operator postfiksa .

Jest to nieco dłużej niż inne rozwiązanie Mathematica, ale pomyślałem, że opublikuję to, ponieważ nie korzysta z Diagonalswbudowanego i używa zupełnie innego podejścia.

Wyjaśnienie

MapIndexed[List,#,{2}]

To najpierw transponuje matrycę (tak, że antydiagonale pojawiają się we właściwej kolejności, jeśli matryca jest spłaszczona). Następnie mapujemy Listkomórki macierzy wraz z indeksem, który zamienia każdy element macierzy iw {i, {x, y}}miejsce xi ywspółrzędne elementu w macierzy.

Join@@...

Spłaszcza to najbardziej zewnętrzny wymiar, dzięki czemu mamy teraz płaską listę elementów macierzy (wraz z ich współrzędnymi) w porządku głównym kolumny.

GatherBy[..., Tr@*Last]

Grupuje te elementy według sumy ich współrzędnych. Zauważ, że antyiagonale są liniami stałej x+y, więc robi to dokładnie to, czego chcemy. Kolejność w każdej grupie jest zachowana. Teraz musimy tylko pozbyć się współrzędnych. Odbywa się to za pomocą dość tajemniczego:

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

To odwzorowuje funkcję #&@@@#&na każdą grupę, która sama dotyczy #& każdego elementu w grupie, i #jest po prostu pierwszym argumentem, tj. Oryginalnym elementem macierzy.

Martin Ender
źródło
Jakieś wyjaśnienie, dlaczego jest czytane jako \[transpose]?
Fatalize
1
@Fatalize Jest to prywatny kod Unicode, a glif Mathematica skojarzony z tym kodem to indeks górny T: reference.wolfram.com/language/ref/character/Transpose.html ... \[Transpose]to po prostu transliteracja tego znaku Unicode w ASCII. Działa kopiowanie znaku Unicode lub transliteracji do Mathematica.
Martin Ender,
2

Oktawa, 77 bajtów

Przy odrobinie nadużycia accumarrayfunkcji:

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

Definiuje to anonimową funkcję. Aby go użyć, przypisz zmienną lub użyj ans.

Dane wejściowe to macierz z :separatorem wierszy. Dane wyjściowe to tablica komórek zawierająca tablicę dla każdego wiersza (odpowiednik oktawowych tablic poszarpanych). Jest to wyświetlane przez Octave pokazujące wskaźniki tablicy komórek i zawartość każdej komórki. Wypróbuj tutaj .

Aby wyświetlić wynik oddzielony tylko spacjami i znakami nowej linii: 83 bajty

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

Możesz także spróbować tutaj .

Luis Mendo
źródło
2

JavaScript (Firefox), 86 75 bajtów

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

Zaoszczędź 11 bajtów dzięki @Neil!

Działa w przeglądarce Firefox 30+. Zajmuje tablicę tablic.

użytkownik 81655
źródło
Niezły algorytm, ale możesz użyć, a.concat(a[0]).slice(1)aby uzyskać tablicę o odpowiedniej długości. Ponadto [for(of)]nie jest ES6; Zwykle piszę to jako (Firefox 30+) lub coś takiego.
Neil,
@ Neil Wow, czuję się trochę głupio, nie zastanawiając się nad użyciem concati slice. Dzięki!
user81655 7.04.16
2

Oktawa, 63 62 bajty

Usunięto jeden bajt dzięki @DonMue ... @LuisMendo!

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

Przeszedłem nudną trasę i zmiażdżyłem antydiagonale.

Próbka uruchomiona na ideone .

zlewka
źródło
Myślę, że można skrócić 'uni'do'un'
Luis Mendo
@LuisMendo Dlaczego tak, mogę! Dzięki! :)
zlewka
2

Haskell, 83 82 bajtów

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

nimi uratował bajt. Dzięki!

Lynn
źródło
1

Python, 128 bajtów (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))
Luis Masuelli
źródło
Witamy w Programowaniu Puzzle i Code Golf! Domyślnie zgłoszenia do kodowania golfowego wyzwania muszą być programami lub funkcjami i używać jednej z zatwierdzonych metod we / wy . Fragment kodu, który oczekuje danych wejściowych w zmiennej zakodowanej na stałe, jest niedozwolony.
Dennis
Wygląda na to, że możesz przerobić pierwsze rozwiązanie, które używa lambdatylko lambda, którego możesz użyć jako przesłanego.
Alex A.
Będę to lambda
Luis Masuelli
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)](jak w oryginalnej wersji) byłby nieco krótszy. Ponadto, należy zmienić A[U][I-U], aby A[I-U][U]uzyskać orientację z pytaniem.
Dennis,
Sprawdzę to po powrocie do domu.
Ma
1

Pyth , 41 17 bajtów

tm_<dx+dYk.T+LaYk

Wypróbuj online!

Zainspirowany rozwiązaniem @ Doorknob na inny problem .

Jak to działa:

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

Poprzednia próba:

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

Wypróbuj online!

Jak to działa:

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

Groovy, 77 73 75

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

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

Spróbuj

EDYCJA: Zapomniałem wysłać odpowiedź, po dodaniu jej wynik wzrasta do 75.

Krzysztof Atłasik
źródło