Rompecabezas Matrix

24

Entrada:

  • Un entero n
  • Dos matrices cuadradas del mismo tamaño (siendo su ancho / alto múltiplo de n)

Salida:

Uno de los dos valores distintos de su elección, uno para resultados verdaderos y otro para resultados falsey (por lo que sí, en 1/0lugar de true/falseresultados válidos para lenguajes como Java, aunque no se consideren valores oficiales de verdad / falsey ).

La salida de verdadero / falso indica si podemos reorganizar bloques de tamaño n by nen una matriz para que sea igual a la otra matriz.

Ejemplo:

Entrada:

Matrix 1:
1 2 3 4 5 6
7 8 9 0 1 2
3 4 5 6 7 8
9 8 7 6 5 4
3 2 1 0 9 8
1 1 1 1 1 1

Matrix 2:
3 2 9 8 7 8
1 1 1 1 5 4
3 4 5 6 1 0
9 0 7 6 1 1
5 6 1 2 3 4
1 2 7 8 9 8

Integer n:
2

Salida: truthy

¿Por qué?

Si dividimos las matrices en bloques de 2 by 2, podemos ver que todos los bloques en una matriz también se pueden encontrar en la otra matriz:

Matrix 1:
1 2 | 3 4 | 5 6
7 8 | 9 0 | 1 2
---------------
3 4 | 5 6 | 7 8
9 8 | 7 6 | 5 4
---------------
3 2 | 1 0 | 9 8
1 1 | 1 1 | 1 1

Matrix 2:
3 2 | 9 8 | 7 8
1 1 | 1 1 | 5 4
---------------
3 4 | 5 6 | 1 0
9 0 | 7 6 | 1 1
---------------
5 6 | 1 2 | 3 4
1 2 | 7 8 | 9 8

Reglas de desafío:

  • Puede suponer que las matrices solo contendrán dígitos no negativos (rango [0,9])
  • Puede suponer que el ancho / alto de las matrices son iguales y un múltiplo de n
  • Puede suponer nque estará en el rango [1, 50], y el ancho / alto de las matrices están en el rango [1,100].
  • Los bloques individuales de n by nsolo se pueden usar una vez para determinar si las matrices son permutaciones entre sí cuando se dividen en bloques de n by n.
  • Puede haber múltiples n by nbloques que sean iguales.
  • Los n by nbloques permanecerán en la misma orientación cuando se verifique si las dos matrices son permutación entre sí cuando se dividen en bloques de n by n.

Reglas generales:

  • Este es el , por lo que la respuesta más corta en bytes gana.
    No permita que los lenguajes de code-golf lo desanimen a publicar respuestas con lenguajes que no sean codegolfing. Trate de encontrar una respuesta lo más breve posible para 'cualquier' lenguaje de programación.
  • Las reglas estándar se aplican a su respuesta con las reglas de E / S predeterminadas , por lo que puede usar STDIN / STDOUT, funciones / método con los parámetros adecuados y programas completos de tipo retorno. Tu llamada.
  • Las lagunas predeterminadas están prohibidas.
  • Si es posible, agregue un enlace con una prueba para su código (es decir, TIO ).
  • Además, se recomienda agregar una explicación para su respuesta.

Casos de prueba:

Input:
Matrix 1:       Matrix 2:       Integer:
1 2 3 4 5 6     3 2 9 8 7 8     2
7 8 9 0 1 2     1 1 1 1 5 4
3 4 5 6 7 8     3 4 5 6 1 0
9 8 7 6 5 4     9 0 7 6 1 1
3 2 1 0 9 8     5 6 1 2 3 4
1 1 1 1 1 1     1 2 7 8 9 8
Output:
truthy

Input:
Matrix 1:       Matrix 2:       Integer:
1 2 3 4 5 6     3 2 9 8 7 8     1
7 8 9 0 1 2     1 1 1 1 5 4
3 4 5 6 7 8     3 4 5 6 1 0
9 8 7 6 5 4     9 0 7 6 1 1
3 2 1 0 9 8     5 6 1 2 3 4
1 1 1 1 1 1     1 2 7 8 9 8
Output:
truthy

Input:
Matrix 1:       Matrix 2:       Integer:
1 2 3 4 5 6     3 2 9 8 7 8     3
7 8 9 0 1 2     1 1 1 1 5 4
3 4 5 6 7 8     3 4 5 6 1 0
9 8 7 6 5 4     9 0 7 6 1 1
3 2 1 0 9 8     5 6 1 2 3 4
1 1 1 1 1 1     1 2 7 8 9 8
Output:
falsey

Input:
Matrix 1:    Matrix 2:    Integer:
1 2 3 4      1 2 3 4      4
2 3 4 5      2 3 4 5
3 4 5 6      3 4 5 6
4 5 6 7      4 5 6 7
Output:
truthy

Input:
Matrix 1:    Matrix 2:    Integer:
1 2 3 4      3 4 3 4      2
2 3 4 5      4 5 4 5
3 4 5 6      1 2 5 6
4 5 6 7      2 3 6 6
Output:
falsey

Input:
Matrix 1:    Matrix 2:    Integer:
1 2          2 3          1
3 4          1 1
Output:
falsey

Input:
Matrix 1:    Matrix 2:    Integer:
0            8            1
Output:
falsey

Input:
Matrix 1:    Matrix 2:    Integer:
1 2 3 4      1 2 1 2      2
5 6 7 8      5 6 5 6
9 0 0 9      0 9 9 0
4 3 2 1      2 1 4 3
Output:
falsey

Input:
Matrix 1:    Matrix 2:    Integer:
1 2 1 2      9 5 1 2      2
3 4 3 4      7 7 3 4
8 3 9 5      1 2 8 3
6 1 7 7      3 4 6 1
Output:
truthy

Input:
Matrix 1:      Matrix 2:      Integer:
1 0 2 0 0 3    1 1 1 0 0 3    2
1 1 1 1 1 1    2 0 1 1 1 1
2 2 2 2 2 2    2 2 2 2 2 2
3 3 3 3 3 3    3 3 3 3 3 3
4 4 4 4 4 4    4 4 4 4 4 4
5 5 5 5 5 5    5 5 5 5 5 5
Output:
falsey

Pastebin con matrices en [[,]]formato.

Kevin Cruijssen
fuente
¿Podemos tomar las matrices como una lista de matrices?
Jo King
@JoKing ¿Te refieres a una lista con ambas matrices en lugar de dos entradas de matriz separadas? Si eso es lo que estás preguntando, entonces por qué no.
Kevin Cruijssen
¿Por qué está [ [ 0 ] ], [ [ 25 ] ], 1presente el ejemplo ? ¿Entendí con You can assume the matrices will only contain non-negative digits (range [0,9])que los valores de la matriz están solo entre 0 y 9?
Olivier Grégoire
2
@ OlivierGrégoire Lo siento, agregó esa regla sobre el rango [0,9]más adelante en el Sandbox. He cambiado el caso de prueba a [[0]],[[8]].
Kevin Cruijssen

Respuestas:

4

Jalea ,  10  9 bytes

ż⁹/ẎsṢʋ€E

Pruébalo en línea! (o con preprocesamiento para copiar y pegar más fácilmente desde los casos de prueba)

Un enlace diádico que acepta una lista de las dos matrices (como listas de listas) a la izquierda y el número entero a la derecha que da 1como resultado 0verdadero o falso, respectivamente.

¿Cómo?

ż⁹/ẎsṢʋ€E - Link: [M1, M2]; N
       €  - for each of [M1, M2]:
      ʋ   -   last four links as a dyad (i.e. f(M, N)):
 ⁹        -     (chain's right argument, N)
 ⁹/       -     N-wise-reduce with:
ż         -       zip together
   Ẏ      -     tighten
    s     -     split into chunks of length N
     Ṣ    -     sort
        E - equal?
Jonathan Allan
fuente
8

APL (Dyalog Extended) , 19 18 17 bytes

-2 gracias a ngn.

Función de infijo tácito anónimo. Toma ncomo argumento izquierdo y la lista de dos matrices como argumento derecho. Requiere indexación cero ( ⎕IO←0). Por cierto, esta función funciona en matrices de cualquier cantidad de dimensiones.

≡.{∧,⍵⊂⍨⊂0=⍺|⍳≢⍵}

Pruébalo en línea!

≡.{... } resultados idénticos de la siguiente función de aplicarse a cada matriz con ncomo ?

≢⍵ tamaño de matriz

 índices 0 ... tamaño – 1

⍺| resto de división cuando se divide por n

 adjuntar para usar en todas las dimensiones

⍵⊂⍨ use eso para dividir * la matriz en una matriz de submatrices
  * comienza una nueva partición cuando el elemento correspondiente es menor que el anterior; elimina elementos marcados por cero

, desentrañar la matriz en una lista de submatrices

 orden ascendente

Adán
fuente
(≢⍵)⍴⍺↑1-> 0=⍺|⍳≢⍵(con ⎕io←0)
ngn
@ngn Gracias. Hecho.
Adám
≡/{}¨->≡.{}
ngn
@ngn Hecho. Gracias.
Adám
6

Perl 6 , 94 68 63 bytes

{[eqv] map *.rotor($^a).map({[Z] $_}).flat.rotor($a²).sort,@_}

Pruébalo en línea!

Bloque de código anónimo que toma la entrada como size, [matrix1, matrix2]y devuelve un valor booleano True/False. Puede haber una forma más eficiente de dividir la matriz en trozos que rotor.

Explicación:

{                                                            }  # Anonymous code block
       map                                                ,@_   # For both matrices 
           *.rotor($^a)   # Split the matrix into N sized chunks
                       .map({[Z] $_})  # Then zip each of those chunks together
                                     .flat  # Flatten the resulting list
                                          .rotor($a²)  # Then split into the NxN lists
                                                     .sort   # And sort them
 [eqv]    # And then check if the lists are equivalent 
Jo King
fuente
4

Java (JDK) , 221 bytes

(n,a,b)->{java.util.Arrays A=null;int l=a.length,x=l/n,i=0,j,z;var c=new String[x*x];A.fill(c,"");var d=c.clone();for(;i<l;i++)for(j=0;j<l;d[z]+=b[i][j++])c[z=i/n+j/n*x]+=a[i][j];A.sort(c);A.sort(d);return A.equals(c,d);}

Pruébalo en línea!

Explicación

La idea es elegir cada celda pequeña como una cadena, que es comparable, y luego ordenar esas cadenas y compararlas en orden.

(n,a,b)->{
 java.util.Arrays A=null;             // Shortcut A for the several java.util.Arrays that'll come
 int l=a.length,x=l/n,i=0,j,z;        // Variable declarations
 var c=new String[x*x];               // Declare the small squares list
 A.fill(c,"");                        // Fill the lists of small squares with the empty string.
 var d=c.clone();                     // Make a copy of the list, for the second matrix
 for(;i<l;i++)
  for(j=0;j<l;d[z]+=b[i][j++])        // For each matrix cell
   c[z=i/n+j/n*x]+=a[i][j];           // Fill the small square with the value, string-wise
 A.sort(c);A.sort(d);                 // Sort both small squares list
 return A.equals(c,d);                // Return true if they're equal, false otherwise.
}

Créditos

  • -12 bytes gracias a Kevin Cruijssen!
Olivier Grégoire
fuente
¿Olvidó jugar al golf for(j=0;j<l;){c[z=i/n+j/n*x]+=a[i][j];d[z]+=b[i][j++];}? .. Puede quitar los soportes colocando todo dentro del bucle. Además, el i=0en el bucle se puede eliminar, porque su iya es 0 en la declaración.
Kevin Cruijssen
Y una cosa para jugar al golf: var d=new String[x*x];puede ser var d=c.clone();en su lugar. 234 bytes
Kevin Cruijssen
PD: ¿Por qué su TIO contiene una cadena que convierte en matrices enteras en 2D? He agregado un contenedor de pasta con los casos de prueba en la parte inferior, para los cuales puede reemplazar el [y ]con {y }y agregar un encabezado new int[][], y hubiera sido suficiente. ;)
Kevin Cruijssen
Maldita sea, no había visto la papelera :( Y por lo demás, todavía estoy jugando al golf. Hice un pase brusco, pero gracias :-)
Olivier Grégoire
El i=0era un remanente cuando me llena los arrays por mí mismo en lugar de utilizar Arrays.fill. Gracias :-) Y por lo cloneque pensé en usarlo, pero todavía pensé que habría devuelto un Objecty no el tipo real. Debo tener varias versiones tarde en ese punto;)
Olivier Grégoire
4

Japt , 18 bytes

®mòV yòV rc n qÃr¥

Pruébalo en línea!

Explicación:

®              Ã      #Apply this to each of the input matrices:
 mòV                  # Split each row into groups of n
     yòV              # Split each column into groups of n
         rc           # Flatten into a list of nxn submatrices
            n         # Sort that list
              q       # Turn it into a string
                r¥    #Return true if both matrices had identical results

El paso "Convertirlo en una cadena" es necesario porque Japt no compara las matrices por valor y la solución incorporada que no funciona para las matrices multidimensionales .

Kamil Drakari
fuente
2
Veré si puedo hacer algo de tiempo entre las reuniones de mañana para tratar de A.e()trabajar para arreglos multidimensionales; Siempre quise volver a ello. Mientras tanto ÕmòV-> yòVle ahorrará un byte.
Shaggy
Por cierto, la limitación en la comparación de matrices para la igualdad es JavaScript en lugar de ser particular de Japt;)
Shaggy
4

TSQL, 164 bytes

Al completar una variable de tabla para tener entrada, esta creación de entrada e inserción de datos no se ha incluido en el recuento de bytes. Solo la consulta real para extraer los datos.

Golfizado (sin incluir la tabla de prueba; se puede encontrar en la versión sin golf):

SELECT iif(exists(SELECT*FROM(SELECT string_agg(v,'')within
group(order by x,y)s,m FROM @t GROUP BY x/@,y/@,m)x
GROUP BY s HAVING max(m)=min(m)or sum(m-.5)<>0),0,1)

Sin golf:

-- test data
DECLARE @ INT = 2
-- x = x-position of the input
-- y = y-position of the input
-- v = value
-- m = matrix(0 or 1)
DECLARE @t table(x int, y int, v int, m int)
--insert first matrix values
INSERT @t values
(0,0,1,0),(0,1,2,0),(0,2,1,0),(0,3,2,0),
(1,0,3,0),(1,1,4,0),(1,2,3,0),(1,3,4,0),
(2,0,8,0),(2,1,3,0),(2,2,9,0),(2,3,5,0),
(3,0,6,0),(3,1,1,0),(3,2,7,0),(3,3,7,0)
INSERT @t values
(0,0,9,1),(0,1,5,1),(0,2,1,1),(0,3,2,1),
(1,0,7,1),(1,1,7,1),(1,2,3,1),(1,3,4,1),
(2,0,1,1),(2,1,2,1),(2,2,8,1),(2,3,3,1),
(3,0,3,1),(3,1,4,1),(3,2,6,1),(3,3,1,1)

-- query
SELECT iif(exists
  (
    SELECT *
    FROM
    (
      SELECT string_agg(v,'')within group(order by x,y)s,m
      FROM @t
      GROUP BY x/@,y/@,m
    ) x
    GROUP BY s
    HAVING max(m)=min(m)or sum(m-.5)<>0
  ),0,1)

Pruébalo

t-clausen.dk
fuente
4

JavaScript (ES6), 88 bytes

(n,a,b)=>(g=a=>a.map((r,y)=>r.map((v,x)=>o[y/n<<7|x/n]+=[v]),o=[])&&o.sort()+o)(a)==g(b)

Pruébalo en línea!

¿Cómo?

Este codigo es:

  • extraer todas las submatrices en cada matriz de entrada como una concatenación de celdas
  • ordenar las submatrices en orden lexicográfico
  • probar si el resultado es el mismo para ambas matrices de entrada

Está aprovechando los límites descritos en el desafío:

  • Una matriz consta de dígitos individuales, por lo que podemos concatenar todas las celdas de una submatriz sin ningún separador y aún así obtener una representación única de la misma (por ejemplo, [[1,2],[3,4]]se puede almacenar como "1234").

  • 100(X,y)yo

    yo=ynorte×128+Xnorte

    o como código JS: y / n << 7 | x << n

Comentado

(n, a, b) =>           // n, a, b = input variables (integer, matrix 1, matrix 2)
  (g = a =>            // g = helper function taking one of the two matrices
    a.map((r, y) =>    // for each row r[] at position y in a[]:
      r.map((v, x) =>  //   for each value v at position x in r[]:
        o[             //     update o[]:
          y / n << 7 | //       the position of the slot is computed by taking advantage
          x / n        //       of the limit on the matrix width (see above)
        ] += [v]       //     coerce v to a string and append it to o[slot]
                       //     all slots are initially undefined, so all resulting strings
                       //     are going to start with "undefined", which is harmless
      ),               //   end of inner map()
      o = []           //   start with o = empty array
    ) &&               // end of outer map()
    o.sort() + o       // sort o[] and coerce it to a string by concatenating it with itself
  )(a) == g(b)         // test whether g(a) is equal to g(b)
Arnauld
fuente
3

Carbón , 54 49 bytes

1FθF⪪ιηF÷L§κ⁰η⊞υEκ§⪪μηλW∧υ⊟υ¿№✂υ⁰⊘⊕Lυ¹ι≔Φυ⁻⌕υιλυ⎚

Pruébalo en línea! El enlace es a la versión detallada del código. Toma datos como una matriz de matrices bidimensionales de igual tamaño. Salidas 1 en caso de éxito, nada en caso de fracaso. Explicación:

1

Asume el éxito.

Fθ

Pase sobre las matrices.

F⪪ιη

Divida la matriz en ntrozos de fila de tamaño.

F÷L§κ⁰η

Pase sobre cada fragmento de columna.

⊞υEκ§⪪μηλ

Extraiga el fragmento de columna para cada fila del fragmento de fila y guarde la submatriz resultante en una lista.

W∧υ⊟υ

Si bien la lista no está vacía, elimine el último fragmento de la lista, que en circunstancias normales proviene de la segunda matriz.

¿№✂υ⁰⊘⊕Lυ¹ι

Cuente el número de ocurrencias de ese fragmento en la primera mitad de la lista, que en circunstancias normales contiene los fragmentos restantes de la primera matriz.

≔Φυ⁻⌕υιλυ

Si no es cero, elimine la primera aparición de ese fragmento de la lista.

Si es cero, borre la salida, haciéndola falsa.

Neil
fuente
2

J , 55 bytes

[:-:/[([:/:~([*-@[)]\,@])"3(((;])@(#@]$1{.~[),;.1])&>])

Pruébalo en línea!

Una solución horrible, solo lo hice funcionar: no tengo poder para jugar golf ...

Galen Ivanov
fuente
2

Haskell, 74 73 bytes

import Data.Lists
i#m|c<-chunksOf i=c.transpose=<<c m
(m!n)i=i#m\\i#n==[]

Nota: TIO no se ha instalado Data.Lists, así que estoy usando Data.Listen su lugar y agrego la función que falta chunksOf: ¡ Pruébelo en línea!

i#m=           -- function '#' makes a list of all transposed jigsaw blocks of matrix 'm'
               -- of size 'i'
 c<-chunksOf i -- define helper function 'c' that splits it's argument into
               -- chunks of site 'i'
         c m   -- split the matrix into chunks of size 'i'
      =<<      -- for each chunk
   transpose   --   transpose
 c.            --   and split into chunks of size 'i', again
               -- flatten one level of nesting ('=<<' is concatMap)

(m!n)i=        -- main function
    i#m\\i#n   -- remove every element of i#n from i#m
      ==[]     -- and check if it results in an empty list  
nimi
fuente
2

C # (compilador interactivo de Visual C #) , 186 bytes

(a,b,n)=>{string[]s(int[][]c){int i=0,j,l=a.Length,m=l/n;var r=new string[m*m];for(;i<l;i++)for(j=0;j<l;)r[i/n*m+j/n]+=c[i][j++];Array.Sort(r);return r;}return s(a).SequenceEqual(s(b));}

Pruébalo en línea!

-1 gracias a @KevinCruijssen!

Menos código de golf:

// anonymous function
// a and b are 2d jagged arrays
// n is the size of the sub matrix
(a,b,n)=>{
  // helper function that translates
  // the sub matrices into strings
  // of digits.
  string[]s(int[][]c){
    // i and j are loop counters
    int i=0,j,
      // l is the size of a side of a matrix
      l=a.Length,
      // m is the number of sub matrices
      // per side of a matrix
      m=l/n;
    // the concatenated digits are
    // stored in a single dimension
    // array
    var r=new string[m*m];
    // nested loops build up
    // the digit strings
    for(;i<l;i++)
      for(j=0;j<l;)
        r[i/n*m+j/n]+=c[i][j++];
    // The resulting array is
    // sorted before it is returned for
    // ease of comparison.
    Array.Sort(r);
    return r;
  }
  return s(a).SequenceEqual(s(b));
}
dana
fuente
Una cosa menor para el golf, j++se puede quitar y colocar +=c[i][j++]+" ";para guardar un byte.
Kevin Cruijssen
Gracias por el consejo :) Curiosamente, se me ocurrió casi la misma solución que la de Java.
dana
1

PHP ,186 163 162 bytes

function($a,$b,$n){$f=function($j,$n){foreach($j as$x=>$r)foreach($r as$y=>$v)$o[count($j)*($x/$n|0)+$y/$n|0].=$v;sort($o);return$o;};return$f($a,$n)==$f($b,$n);}

Pruébalo en línea!

Como todos los buenos desafíos, comencé a pensar que esto era bastante fácil y me arrojó algunas curvas. ¡Bien hecho @Kevin Cruijssen!

Divide la matriz en cadenas que contienen los valores para cada bloque. Las matrices se ordenan y comparan para igualdad.

Sin golf:

function jigsaw_chunk( $j, $n ) {
    foreach( $j as $x => $r ) {
        foreach( $r as $y => $v ) {
            $o[ count( $j ) * floor( $x/$n ) + floor( $y/$n )] .= $v;
        }
    }
    sort( $o );
    return $o;
}

function jigsaw_test( $a, $b, $n ) {
    return jigsaw_chunk( $a, $n ) == jigsaw_chunk( $b, $n );
}

// Test 6
var_dump( jigsaw_test( [[1,2],[3,4]], [[2,3],[1,1]], 1 ) );

Salida

bool(false)
640 KB
fuente
1

Rojas , 148 147 142 bytes

func[a b n][g: func[m][
sort collect[loop k:(length? m)/ n[i: 0
loop k[keep/only
collect[loop n[keep
take/part m/(i: i + 1) n]]]]]](g a)= g b]

Pruébalo en línea!

Galen Ivanov
fuente