Diamondize a Matrix


20

Data una matrice, genera una rappresentazione della matrice in cui l'elemento in alto a sinistra è in alto, l'anti-diagonale è la riga centrale e l'elemento in basso a destra è in fondo.

Ad esempio, considera la seguente matrice:

1 2 3
4 5 6
7 8 9

La versione diamante di questa matrice è:

  1
 4 2
7 5 3
 8 6
  9

Ingressi e uscite

Una matrice di input verrà fornita come un elenco di elenchi (o qualcosa di simile nella tua lingua preferita). L'output deve essere anche un elenco di elenchi.

Le matrici conterranno solo numeri interi positivi.

La matrice di input non sarà necessariamente quadrata.

La matrice di input sarà almeno 1 × 1.

Casi test

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

punteggio

Questo è , quindi vince la risposta più breve in byte.



Related / generalizzazione. (Non lo considererei un duplicato, dal momento che uno consentiva array irregolari e richiedeva la rotazione di qualsiasi multiplo di 45 gradi.)
Martin Ender

Risposte:


19

J, 7 byte

<@|./.

Questo è un verbo monadico senza nome che prende una matrice e restituisce un elenco di antidiagonali:

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

Provalo qui.

Spiegazione

  • /.è incorporato in J per applicare una funzione a ciascuna anti-diagonale. Sfortunatamente, queste anti-diagonali sono date nell'ordine opposto di quello che vogliamo qui.
  • In <@|., per prima |.cosa applichiamo che inverte l'anti-diagonale e quindi <per inscatolarlo (che è l'unico modo per restituire una matrice irregolare in J, poiché le normali matrici sono sempre rettangolari, quindi gli antidiagonali verrebbero riempiti di zero).

Questo è pazzo e bello. Mi prenderò del tempo per imparare questa lingua un giorno.
desiderio di macchina il

5

Python, 91 byte

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

Provalo su Ideone .


Python + NumPy, 69 byte

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

Si aspetta un array NumPy 2D come input e restituisce un elenco di array NumPy. Provalo su Ideone .


4

Gelatina, 7 byte

ṚŒDṙZL$

Provalo online!

Spiegazione

Ṛ         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.

Non conosco Jelly, ma non è di 7 byte se richiede operandi unicode.
Guidobot,

5
@Guidobot Jelly utilizza una code page personalizzata che codifica ciascuno dei 256 caratteri che comprende come un singolo byte.
Dennis,

4

Mathematica, 58 56 byte

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

Funzione anonima, accetta matrici nidificate.


È possibile salvare uno con Length[#]cui è \[Transpose]. E probabilmente un altro dall'aliasing Length.
Sp3000,

O Length@#&@@#per ASCII solo allo stesso numero di byte.
Martin Ender,

3

CJam, 17 byte

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

Un blocco senza nome (funzione) che prevede la matrice in pila e la sostituisce con i suoi antidiagonali.

Provalo qui.

Questo (trovato da Sp3000) funziona per lo stesso conteggio byte:

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

Spiegazione

Questo è meglio spiegato con un esempio. Considera l'input:

[[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 byte

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

Prependi 0s, zip, quindi rimuovi gli elementi falsy. Restituisce un elenco di tuple. Questo serve map(None,...)per eseguire zip_longest (riempire i punti mancanti con None) e filter(None,...)rimuovere elementi falsi.

In modo fastidioso, dobbiamo aggiungere una []riga in più mapper garantire che venga restituito un elenco di tuple, poiché map(None,*[[1]])restituisce [1]anziché [(1,)]per una matrice 1x1. La fila in più viene rimossa dal filterpensiero.

(Grazie a @Dennis per -1 byte)


3

Rubino, 68 66 byte

Funzione anonima.

->l{i=-1;k=[];l.map{|r|i-=j=-1;r.map{|e|k[i+j+=1]=[e,*k[i+j]]}};k}
  • A causa di come funziona l'operatore splat, sono stato in grado di salvare 2 byte rinunciando all'aggiunta dell'array.

2

Mathematica, 60 byte

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

dove è un personaggio Unicode che Mathematica legge come \[Transpose]operatore postfix .

Questo è un po 'più lungo dell'altra soluzione Mathematica, ma ho pensato di pubblicarlo perché non utilizza il Diagonalsbuilt-in e utilizza un approccio completamente diverso.

Spiegazione

MapIndexed[List,#,{2}]

Questo prima traspone la matrice (in modo tale che gli antidiagonali appaiano nell'ordine corretto se la matrice è stata appiattita). Quindi mappiamo Listsulle celle della matrice insieme all'indice, che trasforma ogni elemento della matrice iin {i, {x, y}}dove xe ysono le coordinate dell'elemento nella matrice.

Join@@...

Questo appiattisce la dimensione più esterna, in modo che ora abbiamo un elenco piatto degli elementi della matrice (con le loro coordinate) in ordine di colonna-maggiore.

GatherBy[..., Tr@*Last]

Questo raggruppa quegli elementi per la somma delle loro coordinate. Nota che gli antidiagonali sono linee di costante x+y, quindi questo fa esattamente il raggruppamento che vogliamo. L'ordine all'interno di ciascun gruppo viene preservato. Ora dobbiamo solo liberarci di nuovo delle coordinate. Questo viene fatto tramite il piuttosto criptico:

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

Questo mappa la funzione #&@@@#&su ciascun gruppo, che a sua volta si applica #& a ciascun elemento del gruppo ed #è semplicemente il primo argomento, ovvero l'elemento matrice originale.


Qualche spiegazione sul perché viene letto come \[transpose]?
Fatalizza il

1
@Fatalize È un punto di codice Unicode per uso privato e il glifo Mathematica associato a questo punto di codice è un apice T: reference.wolfram.com/language/ref/character/Transpose.html ... \[Transpose]è semplicemente la traslitterazione ASCII di quel carattere Unicode. La copia del carattere Unicode o della traslitterazione in Mathematica funzionerà.
Martin Ender,

2

Ottava, 77 byte

Con un piccolo abuso della accumarrayfunzione:

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

Questo definisce una funzione anonima. Per usarlo, assegnare a una variabile o utilizzare ans.

L'input è la matrice con :come separatore di riga. L'output è un array di celle contenente un array per ogni riga (l'equivalente di Ottava rispetto agli array frastagliati). Questo viene visualizzato da Octave che mostra gli indici della matrice di celle e il contenuto di ciascuna cella. Provalo qui .

Per visualizzare il risultato separato solo da spazi e righe: 83 byte

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

Puoi anche provarlo qui .


2

JavaScript (Firefox), 86 75 byte

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

Salvato 11 byte grazie a @Neil!

Funziona con Firefox 30+. Accetta una serie di array.


Bell'algoritmo, ma puoi usare a.concat(a[0]).slice(1)per ottenere un array della giusta lunghezza. Inoltre, [for(of)]non è ES6; Normalmente lo scrivo come (Firefox 30+) o alcuni di questi.
Neil,

@Neil Wow, mi sento un po 'sciocco a non capire concate usare slice. Grazie!
user81655

2

Ottava, 63 62 byte

Rimosso un byte grazie a @DonMue ... @LuisMendo!

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

Ho seguito la strada noiosa e ho mescolato gli antidiagonali.

Esempio eseguito su ideone .


Penso che puoi accorciare 'uni'a'un'
Luis Mendo il

@LuisMendo Perché, sì, posso! Grazie! :)
Becher

2

Haskell, 83 82 byte

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

nimi ha salvato un byte. Grazie!


1

Python, 128 byte (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))

Benvenuto in Programmazione di puzzle e codice golf! Per impostazione predefinita, iscrizioni alla sfida di golf del codice devono essere i programmi o funzioni e utilizzo uno dei metodi approvati per I / O . Uno snippet che prevede l'input in una variabile codificata non è consentito.
Dennis,

Sembra che tu possa rielaborare la prima soluzione che utilizza lambdasolo una lambda che puoi usare come presentazione.
Alex A.

Lo lambda
Luis Masuelli il

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)](come nella revisione originale) sarebbe un po 'più breve. Inoltre, dovresti cambiare A[U][I-U]in A[I-U][U]per ottenere l'orientamento dalla domanda.
Dennis,

Lo controllerò quando tornerò a casa.
Ha

1

Pyth , 41 17 byte

tm_<dx+dYk.T+LaYk

Provalo online!

Ispirato dalla soluzione di @ Doorknob a un altro problema .

Come funziona:

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

Tentativo precedente:

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

Provalo online!

Come funziona:

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}

Accetta array di array come input e restituisce array di array.

Provalo

EDIT: ho dimenticato di produrre la risposta, dopo averlo aggiunto il punteggio sale a 75.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.