Diamondizar una matriz

20

Dada una matriz, genere una representación de la matriz donde el elemento superior izquierdo está en la parte superior, el antia diagonal es la fila central y el elemento inferior derecho está en la parte inferior.

Por ejemplo, considere la siguiente matriz:

1 2 3
4 5 6
7 8 9

La versión de diamante de esta matriz es:

  1
 4 2
7 5 3
 8 6
  9

Entradas y salidas

Se proporcionará una matriz de entrada como una lista de listas (o algo similar en el idioma que elija). El resultado también será una lista de listas.

Las matrices solo contendrán enteros positivos.

La matriz de entrada no necesariamente será cuadrada.

La matriz de entrada será al menos 1 × 1.

Casos de prueba

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

Puntuación

Este es el , por lo que gana la respuesta más corta en bytes.

Fatalizar
fuente
Relacionado
Fatalize
Relacionado / Generalización. (Sin embargo, no lo consideraría un engaño, ya que permitía matrices irregulares y requería rotación por cualquier múltiplo de 45 grados.)
Martin Ender
Relacionado.
Martin Ender

Respuestas:

19

J, 7 bytes

<@|./.

Este es un verbo monádico sin nombre que toma una matriz y devuelve una lista de antidiagonales:

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

Pruébalo aquí.

Explicación

  • /.es una función integrada de J para aplicar una función a cada anti-diagonal. Desafortunadamente, estos anti-diagonales se dan en el orden opuesto de lo que queremos aquí.
  • En <@|., aplicamos primero lo |.que invierte el antia diagonal y luego <lo encuadra (que es la única forma de devolver una matriz irregular en J, ya que las matrices normales siempre son rectangulares, por lo que las antidiagonales se rellenarán con ceros).
Martin Ender
fuente
Eso es loco y hermoso. Me tomaré el tiempo de aprender este idioma algún día.
máquina anhelando el
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])]

Pruébalo en Ideone .


Python + NumPy, 69 bytes

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

Espera una matriz NumPy 2D como entrada y devuelve una lista de matrices NumPy. Pruébalo en Ideone .

Dennis
fuente
4

Jalea, 7 bytes

ṚŒDṙZL$

Pruébalo en línea!

Explicación

Ṛ         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
fuente
No sé Jelly, pero eso no es de 7 bytes si requiere operandos unicode.
Guidobot
55
@Guidobot Jelly utiliza una página de códigos personalizada que codifica cada uno de los 256 caracteres que entiende como un solo byte.
Dennis
4

Mathematica, 58 56 bytes

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

Función anónima, toma matrices anidadas.

LegionMammal978
fuente
Puede guardar uno con Length[#]donde está \[Transpose]. Y probablemente otro de alias Length.
Sp3000
O Length@#&@@#para ASCII solo en el mismo recuento de bytes.
Martin Ender
3

CJam, 17 bytes

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

Un bloque (función) sin nombre que espera la matriz en la pila y la reemplaza con sus antidiagonales.

Pruébalo aquí.

Esto (encontrado por Sp3000) funciona para el mismo número de bytes:

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

Explicación

Esto se explica mejor con un ejemplo. Considere la entrada:

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

Anteponga 0s, zip, luego elimine elementos falsos. Devuelve una lista de tuplas. Esto se utiliza map(None,...)para realizar zip_longest (rellenar puntos faltantes con None) y filter(None,...)para eliminar elementos falsos.

De manera molesta, necesitamos agregar una []fila adicional al mappara garantizar que se devuelva una lista de tuplas, ya que map(None,*[[1]])devuelve en [1]lugar de [(1,)]una matriz 1x1. Sin filterembargo, la fila adicional se elimina .

(Gracias a @Dennis por -1 byte)

Sp3000
fuente
3

Ruby, 68 66 bytes

Función anónima.

->l{i=-1;k=[];l.map{|r|i-=j=-1;r.map{|e|k[i+j+=1]=[e,*k[i+j]]}};k}
  • Debido a cómo funciona el operador splat, pude guardar 2 bytes al renunciar a la adición de la matriz.
Tinta de valor
fuente
2

Mathematica, 60 bytes

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

donde es un carácter Unicode que Mathematica lee como el \[Transpose]operador postfix .

Esto es un poco más largo que la otra solución de Mathematica, pero pensé que lo publicaría porque no usa el Diagonalsincorporado y usa un enfoque completamente diferente.

Explicación

MapIndexed[List,#,{2}]

Esto primero transpone la matriz (de modo que las antidiagonales aparezcan en el orden correcto si la matriz se aplana). Luego mapeamos Listsobre las celdas de la matriz junto con el índice, que convierte cada elemento de la matriz ien {i, {x, y}}dónde xy yson las coordenadas del elemento en la matriz.

Join@@...

Esto aplana la dimensión más externa, de modo que ahora tenemos una lista plana de los elementos de la matriz (con sus coordenadas) en orden de columna mayor.

GatherBy[..., Tr@*Last]

Esto agrupa esos elementos por la suma de sus coordenadas. Tenga en cuenta que las antidiagonales son líneas de constante x+y, por lo que esto hace exactamente la agrupación que queremos. Se conserva el orden dentro de cada grupo. Ahora solo necesitamos deshacernos de las coordenadas nuevamente. Esto se hace a través de la críptica:

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

Esto asigna la función #&@@@#&sobre cada grupo, que se aplica #& a cada elemento del grupo, y #es simplemente el primer argumento, es decir, el elemento matriz original.

Martin Ender
fuente
¿Alguna explicación de por qué se lee como \[transpose]?
Fatalize
1
@Fatalize Es un punto de código Unicode de uso privado, y el glifo que Mathematica asocia con este punto de código es un superíndice T: reference.wolfram.com/language/ref/character/Transpose.html ... \[Transpose]es simplemente la transcripción ASCII de ese carácter Unicode. Copiar el carácter Unicode o la transcripción en Mathematica funcionará.
Martin Ender
2

Octava, 77 bytes

Con un pequeño abuso de la accumarrayfunción:

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

Esto define una función anónima. Para usarlo, asigne a una variable o use ans.

La entrada es la matriz con un :separador de filas. La salida es una matriz de celdas que contiene una matriz para cada fila (el equivalente de Octave a las matrices irregulares). Octave lo muestra mostrando los índices de la matriz de celdas y el contenido de cada celda. Probar aquí .

Para mostrar el resultado separado solo por espacios y nuevas líneas: 83 bytes

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

También puedes probarlo aquí .

Luis Mendo
fuente
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())

¡Guardado 11 bytes gracias a @Neil!

Funciona en Firefox 30+. Toma una matriz de matrices.

usuario81655
fuente
Buen algoritmo, pero puede usar a.concat(a[0]).slice(1)para obtener una matriz de la longitud correcta. Además, [for(of)]no es ES6; Normalmente lo escribo como (Firefox 30+) o algo así.
Neil
@Neil Wow, me siento un poco tonto al no saber usar concaty slice. ¡Gracias!
user81655
2

Octava, 63 62 bytes

Eliminado un byte gracias a @DonMue ... @LuisMendo!

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

Fui por la ruta aburrida y mordí las antidiagonales.

Ejecución de muestra en ideone .

cubilete
fuente
Creo que puedes acortar 'uni'a'un'
Luis Mendo
@LuisMendo ¡Sí, sí puedo! ¡Gracias! :)
vaso de precipitados
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 guardó un byte. ¡Gracias!

Lynn
fuente
1

Python, 128 bytes (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
fuente
¡Bienvenido a Programming Puzzles & Code Golf! Por defecto, las presentaciones a desafío de golf de código deben ser programas o funciones y el uso uno de los métodos aprobados para E / S . No se permite un fragmento que espere la entrada en una variable codificada.
Dennis
Parece que puede reelaborar la primera solución que usa lambdaen solo una lambda que puede usar como su envío.
Alex A.
Lo 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)](como en su revisión original) sería un poco más corto. Además, debe cambiar A[U][I-U]a A[I-U][U]para obtener orientación de la pregunta.
Dennis
Lo revisaré cuando regrese a casa. Tiene sentido
Luis Masuelli
1

Pyth , 41 17 bytes

tm_<dx+dYk.T+LaYk

Pruébalo en línea!

Inspirado por la solución de @ Doorknob a otro problema .

Cómo funciona:

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

Intento previo:

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

Pruébalo en línea!

Cómo funciona:

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]
Monja permeable
fuente
1

Groovy, 77 73 75

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

Toma una matriz de matrices como entrada y devuelve una matriz de matrices.

Intentalo

EDITAR: olvidé dar salida a la respuesta, después de agregarlo, la puntuación sube a 75.

Krzysztof Atłasik
fuente