Eine Matrix diamantieren

20

Wenn Sie eine Matrix haben, geben Sie eine Darstellung der Matrix aus, in der sich das obere linke Element oben befindet, die Antidiagonale die mittlere Zeile und das untere rechte Element unten.

Betrachten Sie beispielsweise die folgende Matrix:

1 2 3
4 5 6
7 8 9

Die Diamantversion dieser Matrix ist:

  1
 4 2
7 5 3
 8 6
  9

Eingänge und Ausgänge

Eine Eingabematrix wird als eine Liste von Listen (oder etwas Ähnlichem in der Sprache Ihrer Wahl) angegeben. Die Ausgabe soll ebenfalls eine Liste von Listen sein.

Die Matrizen enthalten nur positive ganze Zahlen.

Die Eingabematrix muss nicht unbedingt quadratisch sein.

Die Eingangsmatrix beträgt mindestens 1 × 1.

Testfälle

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

Wertung

Das ist , also gewinnt die kürzeste Antwort in Bytes.

Tödlich
quelle
Related
Fatalize
Verwandte / Verallgemeinerung. (Ich würde es jedoch nicht für eine Täuschung halten, da dies zerlumpte Arrays zuließ und eine Drehung um ein Vielfaches von 45 Grad erforderte.)
Martin Ender,
Verbunden.
Martin Ender

Antworten:

19

J, 7 Bytes

<@|./.

Dies ist ein unbenanntes monadisches Verb, das eine Matrix verwendet und eine Liste von Antidiagonalen zurückgibt:

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

Teste es hier.

Erläuterung

  • /.ist in J integriert, um eine Funktion auf jede Antidiagonale anzuwenden. Leider werden diese Antidiagonalen in der entgegengesetzten Reihenfolge wie hier angegeben.
  • In <@|.wenden wir zuerst an, |.was <die Antidiagonale umkehrt, und dann , um sie zu boxen (was die einzige Möglichkeit ist, ein unregelmäßiges Array in J zurückzugeben, da normale Arrays immer rechteckig sind, sodass die Antidiagonalen mit Nullen aufgefüllt würden).
Martin Ender
quelle
Das ist verrückt und schön. Ich werde mir die Zeit nehmen, diese Sprache eines Tages zu lernen.
Maschine Sehnsucht
5

Python, 91 Bytes

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

Teste es auf Ideone .


Python + NumPy, 69 Bytes

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

Erwartet ein 2D-NumPy-Array als Eingabe und gibt eine Liste von NumPy-Arrays zurück. Teste es auf Ideone .

Dennis
quelle
4

Gelee, 7 Bytes

ṚŒDṙZL$

Probieren Sie es online!

Erläuterung

Ṛ         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
quelle
Ich kenne Jelly nicht, aber das sind keine 7 Bytes, wenn Unicode-Operanden erforderlich sind.
Guidobot
5
@ Guidobot Jelly verwendet eine benutzerdefinierte Codepage , die jedes der 256 Zeichen, die es versteht, als einzelnes Byte codiert.
Dennis
4

Mathematica, 58 56 Bytes

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

Anonyme Funktion, nimmt verschachtelte Arrays.

LegionMammal978
quelle
Sie können eine mit Length[#]wo ist speichern \[Transpose]. Und wahrscheinlich eine andere von Aliasing Length.
Sp3000
Oder Length@#&@@#für ASCII nur bei gleicher Bytezahl.
Martin Ender
3

CJam, 17 Bytes

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

Ein unbenannter Block (Funktion), der die Matrix auf dem Stapel erwartet und durch ihre Antidiagonalen ersetzt.

Teste es hier.

Dies (gefunden von Sp3000) funktioniert für die gleiche Byteanzahl:

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

Erläuterung

Dies lässt sich am besten anhand eines Beispiels erklären. Betrachten Sie die Eingabe:

[[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
quelle
3

Python 2, 88 87 Bytes

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

Stellen Sie 0s voran, zip und entfernen Sie dann falsche Elemente. Gibt eine Liste von Tupeln zurück. Dies wird verwendet map(None,...), um zip_longest fehlende Stellen aufzufüllen Noneund filter(None,...)fehlerhafte Elemente zu entfernen.

Nervend, brauchen wir eine zusätzliche hinzuzufügen []Reihe der mapzu gewährleisten , dass eine Liste von Tupeln zurückgegeben wird, da map(None,*[[1]])kehrt [1]anstatt [(1,)]für eine 1x1 - Matrix. Die zusätzliche Reihe wird durch das filterzwar abgestreift .

(Danke an @Dennis für -1 Byte)

Sp3000
quelle
3

Ruby, 68 66 Bytes

Anonyme Funktion.

->l{i=-1;k=[];l.map{|r|i-=j=-1;r.map{|e|k[i+j+=1]=[e,*k[i+j]]}};k}
  • Aufgrund der Funktionsweise des splat-Operators konnte ich 2 Bytes einsparen, indem ich auf das Hinzufügen des Arrays verzichtete.
Wert Tinte
quelle
2

Mathematica, 60 Bytes

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

Dabei handelt es sich um ein Unicode-Zeichen, das Mathematica als Postfix- \[Transpose]Operator liest .

Dies ist ein bisschen länger als die andere Mathematica-Lösung, aber ich dachte, ich würde es veröffentlichen, weil es nicht das Diagonalseingebaute verwendet und einen völlig anderen Ansatz verwendet.

Erläuterung

MapIndexed[List,#,{2}]

Dies transponiert zuerst die Matrix (so dass die Antidiagonalen in der richtigen Reihenfolge erscheinen, wenn die Matrix abgeflacht wurde). Dann bilden wir Listdie Zellen der Matrix zusammen mit dem Index ab, der jedes Matrixelement iin {i, {x, y}}wo xund ysind die Koordinaten des Elements in der Matrix.

Join@@...

Dadurch wird die äußerste Dimension abgeflacht, sodass wir nun eine flache Liste der Matrixelemente (mit ihren Koordinaten) in Spalten-Hauptreihenfolge haben.

GatherBy[..., Tr@*Last]

Dies gruppiert diese Elemente nach der Summe ihrer Koordinaten. Beachten Sie, dass Antidiagonale konstante Linien sind. x+yDies entspricht also genau der von uns gewünschten Gruppierung. Die Reihenfolge innerhalb jeder Gruppe bleibt erhalten. Jetzt müssen wir nur noch einmal die Koordinaten loswerden. Dies geschieht über die eher kryptischen:

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

Dies ordnet die Funktion #&@@@#&jeder Gruppe zu, die sich auf jedes Element in der Gruppe bezieht #& , und #ist einfach das erste Argument, dh das ursprüngliche Matrixelement.

Martin Ender
quelle
Irgendeine Erklärung, warum als gelesen wird \[transpose]?
Fatalize
1
@Fatalize Es ist ein Unicode-Codepunkt für den privaten Gebrauch, und die mit diesem Codepunkt verknüpfte Glyphe Mathematica ist hochgestellt T: reference.wolfram.com/language/ref/character/Transpose.html ... \[Transpose]ist einfach die ASCII-Transliteration dieses Unicode-Zeichens. Das Kopieren des Unicode-Zeichens oder der Transliteration in Mathematica funktioniert.
Martin Ender
2

Oktave, 77 Bytes

Mit ein wenig Missbrauch der accumarrayFunktion:

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

Dies definiert eine anonyme Funktion. Um es zu verwenden, weisen Sie es einer Variablen zu oder verwenden Sie ans.

Eingabe ist die Matrix mit :als Zeilentrennzeichen. Die Ausgabe ist ein Zellenarray, das ein Array für jede Zeile enthält (Oktav entspricht gezackten Arrays). Dies wird durch Octave angezeigt, wobei die Indizes des Zellenfeldes und der Inhalt jeder Zelle angezeigt werden. Probieren Sie es hier aus .

So zeigen Sie das Ergebnis nur durch Leerzeichen und Zeilenumbrüche getrennt an: 83 Byte

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

Sie können es auch hier ausprobieren .

Luis Mendo
quelle
2

JavaScript (Firefox), 86 75 Bytes

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

11 Bytes dank @Neil gespart!

Funktioniert in Firefox 30+. Nimmt ein Array von Arrays.

user81655
quelle
Nizza Algorithmus, aber Sie können verwenden a.concat(a[0]).slice(1), um ein Array mit der richtigen Länge zu erhalten. Auch [for(of)]ist nicht ES6; Normalerweise schreibe ich es als (Firefox 30+) oder so.
Neil
@Neil Wow, ich fühle mich ein bisschen dumm, nicht herauszufinden, zu verwenden concatund slice. Vielen Dank!
user81655
2

Oktave, 63 62 Bytes

Ein Byte entfernt dank @DonMue ... @LuisMendo!

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

Ich bin den langweiligen Weg gegangen und habe die Antidiagonalen gemengt.

Probelauf auf ideone .

Becherglas
quelle
Ich glaube , Sie verkürzen können 'uni'zu'un'
Luis Mendo
@ LuisMendo Warum, ja, ich kann! Vielen Dank! :)
Becher
2

Haskell, 83 82 Bytes

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

nimi hat ein byte gespeichert. Vielen Dank!

Lynn
quelle
1

Python, 128 Bytes (Anzahl)

(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
quelle
Willkommen bei Programming Puzzles & Code Golf! Standardmäßig müssen Einsendungen zur Code-Golf-Challenge Programme oder Funktionen sein und eine der genehmigten Methoden für E / A verwenden . Ein Snippet, das die Eingabe in eine fest codierte Variable erwartet, ist nicht zulässig.
Dennis
Anscheinend können Sie die erste Lösung, die verwendet wird, lambdain ein Lambda umwandeln, das Sie als Vorlage verwenden können.
Alex A.
Ich werde es 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)](wie in deiner ursprünglichen Revision) wäre etwas kürzer. Sie sollten auch zu wechseln A[U][I-U], A[I-U][U]um sich an der Frage zu orientieren.
Dennis
Ich werde es überprüfen, wenn ich wieder zu Hause bin. Das macht Sinn
Luis Masuelli
1

Pyth , 41 17 Bytes

tm_<dx+dYk.T+LaYk

Probieren Sie es online!

Inspiriert von @ Doorknobs Lösung für ein anderes Problem .

Wie es funktioniert:

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

Vorheriger Versuch:

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

Probieren Sie es online!

Wie es funktioniert:

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]
Undichte Nonne
quelle
1

Groovy, 77 73 75

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

Nimmt Array von Arrays als Eingabe und gibt Array von Arrays zurück.

Versuch es

EDIT: Ich habe vergessen, die Antwort auszugeben, nachdem ich sie hinzugefügt habe, steigt die Punktzahl auf 75.

Krzysztof Atłasik
quelle