Generar todas las submatrices cuadradas de un tamaño dado.

14

Se le dará una matriz cuadrada de números enteros M y otro número entero positivo n , estrictamente menor que el tamaño de M . Su tarea es generar todas las submatrices cuadradas de M de tamaño n .

Para los fines de este desafío, una sub-matriz cuadrada es un grupo de adyacentes filas y columnas contenida en M .

Formatos de entrada / salida

Usted es libre de elegir cualquier otro formato razonable, estos son solo algunos ejemplos.

Entrada

  • Una matriz en el tipo de matriz nativa (si su idioma tiene uno)
  • Una matriz 2D (una matriz de matrices 1D, cada una correspondiente a una fila / una columna)
  • Una matriz 1D (ya que la matriz siempre es cuadrada)
  • Una cadena (elegiste el espacio, pero no abuses de esto de ninguna manera), etc.

Salida

  • Una matriz de matrices.
  • Una matriz 4D, donde cada elemento (lista 3D) representa las submatrices en una fila / columna.
  • Una matriz 3D, donde cada elemento (lista 2D) representa una submatriz.
  • Una representación de cadena de las submatrices resultantes, etc.

Especificaciones

  • También puede elegir tomar el tamaño de M como entrada. Se garantiza que sea al menos 2 .
  • La orientación de la salida es arbitraria: puede optar por generar las submatrices como listas de columnas o listas de filas, pero su elección debe ser coherente.
  • Puede competir en cualquier lenguaje de programación y puede tomar entradas y proporcionar salidas a través de cualquier método estándar , mientras toma nota de que estas lagunas están prohibidas por defecto.
  • Este es el , por lo que gana el envío más corto (en bytes) para cada idioma .

Ejemplo

Dado n = 3 y M :

 1 2 3 4
 5 6 7 8
 9 10 11 12
13 14 15 16

Las posibles submatrices 3x3 son:

+ ------- + + -------- + 1 2 3 4 1 2 3 4
| 1 2 3 | 4 1 | 2 3 4 | + -------- + + -------- +
| 5 6 7 | 8 5 | 6 7 8 | | 5 6 7 | 8 5 | 6 7 8 |
| 9 10 11 | 12 9 | 10 11 12 | | 9 10 11 | 12 9 | 10 11 12 |
+ ------- + + -------- + | 13 14 15 | 16 13 | 14 15 16 |
13 14 15 16 13 14 15 16 + -------- + + -------- +

Entonces el resultado sería:

[[[1, 2, 3], [5, 6, 7], [9, 10, 11]], [[2, 3, 4], [6, 7, 8], [10, 11, 12]], [[5, 6, 7], [9, 10, 11], [13, 14, 15]], [[6, 7, 8], [10, 11, 12], [14, 15, 16]]]

Como se señaló anteriormente, una salida de:

[[[1, 5, 9], [2, 6, 10], [3, 7, 11]], [[2, 6, 10], [3, 7, 11], [4, 8, 12]], [[5, 9, 13], [6, 10, 14], [7, 11, 15]], [[6, 10, 14], [7, 11, 15], [8, 12, 16]]]

también sería aceptable si elige devolver las submatrices como listas de filas.

Casos de prueba

Las entradas M, n :

[[1,2,3],[5,6,7],[9,10,11]], 1
[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]], 3
[[100,-3,4,6],[12,11,14,8],[0,0,9,3],[34,289,-18,3]], 2
[[100,-3,4,6],[12,11,14,8],[9,10,11,12],[13,14,15,16]], 3

Y las salidas correspondientes (submatrices dadas como listas de filas):

[[[1]],[[2]],[[3]],[[5]],[[6]],[[7]],[[9]],[[10]],[[11]]]
[[[1,2,3],[5,6,7],[9,10,11]],[[2,3,4],[6,7,8],[10,11,12]],[[5,6,7],[9,10,11],[13,14,15]],[[6,7,8],[10,11,12],[14,15,16]]]
[[[100,-3],[12,11]],[[-3,4],[11,14]],[[4,6],[14,8]],[[12,11],[0,0]],[[11,14],[0,9]],[[14,8],[9,3]],[[0,0],[34,289]],[[0,9],[289,-18]],[[9,3],[-18,3]]]
[[[100,-3,4],[12,11,14],[9,10,11]],[[-3,4,6],[11,14,8],[10,11,12]],[[12,11,14],[9,10,11],[13,14,15]],[[11,14,8],[10,11,12],[14,15,16]]]

O, como listas de columnas:

[[[1]],[[2]],[[3]],[[5]],[[6]],[[7]],[[9]],[[10]],[[11]]]
[[[1,5,9],[2,6,10],[3,7,11]],[[2,6,10],[3,7,11],[4,8,12]],[[5,9,13],[6,10,14],[7,11,15]],[[6,10,14],[7,11,15],[8,12,16]]]
[[[100,12],[-3,11]],[[-3,11],[4,14]],[[4,14],[6,8]],[[12,0],[11,0]],[[11,0],[14,9]],[[14,9],[8,3]],[[0,34],[0,289]],[[0,289],[9,-18]],[[9,-18],[3,3]]]
[[[100,12,9],[-3,11,10],[4,14,11]],[[-3,11,10],[4,14,11],[6,8,12]],[[12,9,13],[11,10,14],[14,11,15]],[[11,10,14],[14,11,15],[8,12,16]]]]
Sr. Xcoder
fuente
Publicación de Sandbox (ahora eliminada, solo los usuarios con más de 2k de reputación pueden verla). Gracias a todos los que han dado su opinión.
Sr. Xcoder
Entonces, ¿está permitido este formato de salida ?
Luis Mendo
@LuisMendo Sí, está permitido.
Sr. Xcoder

Respuestas:

6

05AB1E , 8 bytes

2FεŒsù}ø

Pruébalo en línea!

Explicación

2F            # 2 times do:
  ε    }      # apply to each element in the input matrix (initially rows)
   Œsù        # get a list of sublists of size input_2
        ø     # transpose (handling columns on the second pass of the loop)
Emigna
fuente
5

MATL , 4 bytes

thYC

Las entradas son n, entonces M.

La salida es una matriz, donde cada columna contiene todas las columnas de una submatriz.

Pruébalo en línea!

Explicación

thY    % Address the compiler with a formal, slightly old-fashioned determiner
C      % Convert input to ouput

Más en serio, ttoma la entrada n implícitamente y la duplica en la pila. hconcatena ambas copias de n , produciendo la matriz [n, n] . YCtoma la entrada M implícitamente, extrae todos sus bloques de tamaño [n, n] y los organiza como columnas en el orden de columnas principales. Esto significa que las columnas de cada bloque se apilan verticalmente para formar una sola columna.

Luis Mendo
fuente
1
LOL +1 para "pronombre formal, algo anticuado", y un muy buen golf.
Giuseppe
@Giuseppe Me acabo de dar cuenta de que es un determinante, no un pronombre: - /
Luis Mendo
Bueno, siempre aprendí "tu / tu" como pronombres posesivos; Esta es la primera vez que oigo hablar de un determinante.
Giuseppe
@Giuseppe "Thy / your" son determinantes posesivos, es decir, van con un nombre: "Este es tu auto". "Tuyo / tuyo" son pronombres posesivos, es decir, el nombre se omite: "Esto es tuyo". E inicialmente confundí "tu" con un pronombre personal, que en realidad sería "tú". Qué desastre he hecho :-)
Luis Mendo
4

APL (Dyalog Unicode) , SBCS de 26 bytes

Infix anónimo lambda tomando n como argumento izquierdo y M como argumento derecho.

{s↓(-s2⍴⌈¯1+⍺÷2)↓⊢⌺⍺ ⍺⊢⍵}

Pruébalo en línea!

{} Lambda anónima donde es el argumento izquierdo y es el argumento correcto:

⊢⍵ producir el argumento correcto (se separa ⍺ ⍺de )

⊢⌺⍺ ⍺ todas las submatrices, incluidas las que se superponen a los bordes (se rellenan con ceros)

()↓ Suelte los siguientes elementos numéricos a lo largo de las dos primeras dimensiones:

  ⍺÷2 medio de

  ¯1+ uno negativo más eso

   redondeo

  2⍴ cíclicamente r eshape a una lista de dos elementos

  s← almacenar en s(para s hard)

  - negar (es decir, dejar caer desde la parte trasera)

s↓soltar selementos a lo largo de la primera y segunda dimensiones (desde el frente)

Adán
fuente
4

APL (Dyalog Unicode) , 31 bytes

{(12 1 3 4⍉⊖)⍣(4×⌊⍺÷2)⊢⌺⍺ ⍺⊢⍵}

Pruébalo en línea!

Un enfoque diferente al de Adám.

Erik el Outgolfer
fuente
¿Pretendes dar una explicación (después de que hayas terminado de jugar golf, por supuesto)? Me interesaría ver cómo funciona (y no sé APL en absoluto) :)
Emigna
@Emigna Sí, si tengo tiempo para entonces.
Erik the Outgolfer
Muy inteligente. Si puede usar con éxito dyadic para casos no triviales, entonces realmente ha dominado la programación de arreglos.
Adám
@ Adám Uh, aunque creo que esta respuesta no es válida :-( EDITAR: Corregido, pero ahora tiene 31 bytes de largo ...
Erik the Outgolfer
Siéntase libre de copiar el conjunto de pruebas de mi envío.
Adám
3

R , 75 bytes

function(M,N,S,W=1:N,g=N:S-N)for(i in g)for(j in g)print(M[i+W,j+W,drop=F])

Pruébalo en línea!

Toma M, Ny el Stamaño de la matriz.

Imprime las matrices resultantes en stdout; drop=Fes necesario para que, en el N=1caso de que la indexación no elimine el dimatributo y produzca a en matrixlugar de a vector.

Giuseppe
fuente
3

J , 11 8 bytes

-3 bytes gracias a millas

<;._3~,~

Pruébalo en línea!

Galen Ivanov
fuente
1
Esto usa 8 bytes <;._3~,~y usa un gancho para emparejar el tamaño consigo mismo, luego corta y encajona cada uno ya que se permite una matriz de matrices como salida.
millas
@miles ¡Gracias, es elegante ahora!
Galen Ivanov
2

Jalea , 5 bytes

Z⁹Ƥ⁺€

Utiliza el formato de salida 4D. Para 3D, agregue un de 6 bytes .

Pruébalo en línea!

Cómo funciona

Z⁹Ƥ⁺€  Main link. Left argument: M (matrix). Right argument: n (integer)

 ⁹Ƥ    Apply the link to the left to all infixes of length n.
Z        Zip the rows of the infix, transposing rows and columns.
   ⁺€  Map Z⁹Ƥ over all results.
Dennis
fuente
Sugerí algo similar a user202729 en el chat. Una alternativa de 5 bytes es ṡ€Zṡ€.
Sr. Xcoder
2

Brachylog , 13 bytes

{tN&s₎\;Ns₎}ᶠ

Pruébalo en línea!

Esto devuelve listas de columnas.

Técnicamente, tN&s₎\;Ns₎es un predicado generador que unifica su salida con cualquiera de esas submatrices. Usamos {…}ᶠsolo para exponer todas las posibilidades.

Explicación

 tN&              Call the second argument of the input N
{          }ᶠ     Find all:
    s₎              A substring of the matrix of size N
      \             Transpose that substring
       ;Ns₎         A substring of that transposed substring of size N
Fatalizar
fuente
1

Stax , 10 bytes

│Æ☼♂Mqß E╖

Ejecutarlo

La representación ascii del mismo programa es

YBFMyBF|PMmJ

Funciona así.

Y               Store the number in the y register
 B              Batch the grid into y rows each
  F             Foreach batch, run the rest of the program
   M            Transpose about the diagonal
    yB          Batch the transposed slices into y rows each
      F         Foreach batch, run the rest of the progoram
       |P       Print a blank line
         M      Transpose inner slice - restoring its original orientation
          mJ    For each row in the inner grid, output joined by spaces
recursivo
fuente
1

JavaScript (ES6), 91 bytes

Toma entrada en la sintaxis de curry (a)(n). Devuelve los resultados como listas de filas.

a=>n=>(g=x=>a[y+n-1]?[a.slice(y,y+n).map(r=>r.slice(x,x+n)),...g(a[x+n]?x+1:!++y)]:[])(y=0)

Casos de prueba

Arnauld
fuente
1

APL (Dyalog Classic) , 24 23 bytes

t∘↑¨(¯1-t←-2⍴⎕)↓,⍀⍪\⍪¨⎕

Pruébalo en línea!

el resultado es una matriz de matrices, aunque el formato de salida de Dyalog no lo hace muy obvio

ingrese la matriz ( ), convierta cada elemento en una matriz anidada propia ( ⍪¨), tome concatenaciones de prefijo por fila ( ,\) y por columna ( ⍪⍀), ingrese n ( ), suelte las primeras filas n-1 y columnas de matrices anidadas ( (¯1-t←-2⍴⎕)↓), tome la esquina inferior derecha n-por-n de cada matriz ( t∘↑¨)

                                        ┌─┬──┬───┐
                                        aababc      ┼──┼───┤        ┼──┼───┤
 n=2       ┌─┬─┬─┐      ┌─┬──┬───┐      ├─┼──┼───┤      ababc        ab bc
┌───┐      abc      aabbac      aababc      dedef        de ef
abc  ⍪¨  ├─┼─┼─┤  ,\  ├─┼──┼───┤  ⍪⍀  ddedef 1 1 ┼──┼───┤¯2 ¯2∘↑¨┼──┼───┤
def ---> def ---> ddeedf ---> ├─┼──┼───┤ ---> ababc  --->       
ghi      ├─┼─┼─┤      ├─┼──┼───┤      aababc      dedef        de ef
└───┘      ghi      gghhgi      ddedef      ghghi        gh hi
           └─┴─┴─┘      └─┴──┴───┘      gghghi      ┴──┴───┘        ┴──┴───┘
                                        └─┴──┴───┘
ngn
fuente
0

Ruby , 63 bytes

->c,g{n=c.size-g+1
(0...n*n).map{|i|c[i/n,g].map{|z|z[i%n,g]}}}

Pruébalo en línea!

Esta es una lambda que toma una matriz 2D y una int, devolviendo una matriz 3D.

Sin golf:

->m,n{
  a = m.size - n + 1     # The count of rows in m that can be a first row in a submatrix
  (0...a*a).map{ |b|     # There will be a*a submatrices
    m[b/a,n].map{ |r|    # Take each possible set of n rows
      r[b%a,n]           # And each possible set of n columns
    }
  }
}
benj2240
fuente
0

Python 2 , 91 bytes

lambda a,n:(lambda R:[[r[i:i+n]for r in a[j:j+n]]for i in R for j in R])(range(len(a)+1-n))

Pruébalo en línea!

Chas Brown
fuente
def f(a,n):R=range(len(a)+1-n);print[[r[i:i+n]for r in a[j:j+n]]for i in R for j in R]ahorra cinco.
Jonathan Allan