¿Es este un tablero válido de Takuzu?


21

Takuzu es un juego de lógica en el que debes completar una cuadrícula con celdas que contienen 0sy 1s. La cuadrícula debe seguir 3 reglas:

  1. No hay tres celdas consecutivas horizontales o verticales que puedan ser iguales.
  2. Debe haber un número igual de 0s y 1s en cada fila y columna.
  3. No hay dos filas iguales, y no hay dos columnas iguales.

Veamos una cuadrícula terminada:

0011
1100
0101
1010

Como puede ver, este tablero sigue la regla 1, 2y 3. No hay tres celdas horizontales o verticales que sean iguales, todas las filas y columnas contienen un número igual de 0sy 1s, y no hay dos filas ni dos columnas iguales.

Veamos una cuadrícula que no es válida:

110100
010011
011010
101100
100011
001101

Hay muchos problemas con esta cuadrícula. Por ejemplo, la fila 5tiene tres 0s seguidas y la columna 2tiene tres 1s seguidas, seguidas de tres 0s. Por lo tanto, esta no es una cuadrícula válida.

Tarea:

Su tarea es hacer un programa que, dada una matriz 2D de n* n 0s y 1s, verifica el tablero para ver si es una tabla válida, acabada Takuzu.

Ejemplos:

0011
1100
0101
1010

Este tablero sigue todas las reglas y, por lo tanto, es un tablero válido de Takuzu. Debe devolver un valor verdadero para esto.

11
00

Este no es un tablero válido: la fila 1no sigue la regla 2. Debe devolver un valor falso para esto.

100110
101001
010101
100110
011010
011001

Este no es un tablero válido, falla (solo) debido a la regla 3: la primera y la cuarta fila son las mismas.

110100
001011
010011
101100
100110
011001

Este no es un tablero válido, falla (solo) debido a la regla 3: la primera y la cuarta columna son iguales.

011010
010101
101100
010011
100110
101001

Este es un tablero válido.

Reglas y especificaciones:

  • Puede suponer que todos los tableros son cuadrados de dimensiones n * n, donde nes un número entero positivo.
  • Puede suponer que todas las tablas están terminadas.
  • Puede tomar la entrada como una matriz 2D que contiene valores que significan 0y 1, o como una cadena.
  • Debe generar valores consistentes de verdad y falsey para las tablas de verdad y falsey, y los valores que representan "verdad" y "falsey" no pueden ser los mismos.

Este es el , por lo que gana el código más corto en bytes.



3
Sé esto como 0h h1 ...
Erik the Outgolfer

3
@EriktheOutgolfer Sí, comencé solo sabiendo esto como 0h h1 también, pero Takuzu es el nombre original del rompecabezas.
clismique

@EriktheOutgolfer Siempre lo supe como "Rompecabezas binario" o "Subiku", pero "Takuzu" es como Qwerp-Derp mencionó el nombre original.
Kevin Cruijssen

2
Sería bueno tener más casos de prueba (me faltan tablas grandes y válidas)
Lynn el

Respuestas:


16

Brachylog , 20 18 bytes

≠\≠,?¬{∋s₃=|∋ọtᵐ≠}

Pruébalo en línea!

Explicación

≠                           All rows are different
 \                          Transpose
  ≠                         All columns are different
   ,?                       Append the list of rows to the list of columns
     ¬{          }          It is impossible that:
       ∋                      A row/column of the matrix…
        s₃=                   …contains a substring of 3 equal elements
           |                Or that:
            ∋ọ                The occurences of 1s and 0s in a row/column…
              tᵐ≠             …are not equal

Agregue la lista de filas a la lista de columnas " de manera inteligente para jugar golf! Y aquí pensé que tu respuesta de 20 bytes era ir al grano y jugar al golf lo más posible. Veo que Brachylog es tan bueno para validar las matrices como para resolverlas . :)
Kevin Cruijssen

1
¿No debería salir falsepara esto ?
H.PWiz

1
@ H.PWiz Buen hallazgo, gracias. Revertido a la versión de 18 bytes que funcionó.
Fatalize

@LuisMendo Solo estoy poniendo todas las filas y todas las columnas en la misma lista básicamente.
Fatalize

2
@ Zgarb Correcto, gracias. Es la tercera vez que he tenido de revertir una edición, el puesto de apertura es una urgente necesidad de mejores casos de prueba ...
Fatalize

11

Casco , 19 18 bytes

S=‼(Tf§=LṁDum(ṁ↑2g

Pruébalo en línea!

1 byte guardado gracias a H.PWiz!

La idea principal es aplicar una serie de transformaciones a la entrada que son identidades para una placa válida y verificar si el resultado final es el mismo que la entrada original.

Explicación

S=‼(Tf§=LṁDum(ṁ↑2g
            m(ṁ↑2g    in each line, take at most two items for each sequence of equal items
           u          remove duplicate lines
     f§=LṁD          keep only those lines where the sum of each element doubled is equal to the length of the line
    T                 transpose the matrix (swap rows with columns)
  ‼                   do all the previous operations again
S=                    check if the final result is equal to the original input

2
Algunos cambios para eliminar un)
H.PWiz

@ H.PWiz que era casi obvio, ¡tonto!
Leo

7

Jalea , 17 bytes

-*S;E3Ƥ€F$TȯQZµ⁺⁼

Pruébalo en línea!

-6 bytes gracias a millas y Jonathan Allan .


1
Creo que puedes acortar esto a 21 bytes. TIO
millas

@miles ... ¿tal vez incluso 19 bytes ?
Jonathan Allan

1
@JonathanAllan son 18 bytes ... sí, lo hiciste de µZ$⁺nuevo: p ... y 17 bytes intercambiando un poco: D ahora
vencí

@EriktheOutgolfer ¡Ya no, es un empate!
Fatalize

@JonathanAllan Nice. También creo que esta es la primera vez que el prefijo / infijo rápido que agregué ha sido útil.
millas

5

Mathematica, 143 bytes

And@@Flatten@(((s=#;Equal@@(Count[s,#]&/@{0,1})&&FreeQ[Subsequences@s,#]&/@{{1,1,1},{0,0,0}})&/@#)&&(DeleteDuplicates@#==#)&/@{#,Transpose@#})&


entrada

[{{0, 0, 1, 1}, {1, 1, 0, 0}, {0, 1, 0, 1}, {1, 0, 1, 0}}]


5

Python 2 , 127 bytes

a=input()
n=len(a)
b=zip(*a)
print[n/2]*n*2==map(sum,a+b)>len(set(a))==len(set(b))==n<'0, 0, 0'not in`a+b`>'1, 1, 1'not in`a+b`

Pruébalo en línea!

Lee una lista de n n -tuplas como entrada.

Podría generar el código de salida escribiendo en 1/(…)lugar de hacerlo, print…pero se siente escoria. ¿Debería?

Explicación

nes el tamaño del tablero; bes una lista de columnas (transposición de a). El resto es una comparación largamente encadenada:

  • [n/2]*n*2==map(sum,a+b) verifica la regla 2. Cada fila y columna debe sumar n / 2.
  • map(sum,a+b)>len(set(a)) siempre es cierto (list> int).
  • len(set(a))==len(set(b))==n verifica la regla 3.
  • n<'0, 0, 0' siempre es cierto (int <str).
  • '0, 0, 0'not in`a+b`>'1, 1, 1'not in`a+b`comprueba la regla 1. `a+b`es la representación de cadena de todas las filas y columnas; para la entrada de ejemplo en TIO es

    "[(0, 0, 1, 1), (1, 1, 0, 0), (0, 1, 0, 1), (1, 0, 1, 0), (0, 1, 0, 1), (0, 1, 1, 0), (1, 0, 0, 1), (1, 0, 1, 0)]"

    El `a+b`>'1, 1, 1'en el centro siempre es cierto ya que esta cadena está garantizada para comenzar "[", que es mayor que "1".


Si desea generar un código de salida, puede hacerlo [n/2]*n*2==map(sum,a+b)>len(set(a))==len(set(b))==n<'0, 0, 0'not in`a+b`>'1, 1, 1'not in`a+b`>x, que es 2 bytes más corto que la división y da como resultado NameErrorentradas verdaderas.
ovs

3

Casco , 27 25 bytes

Λ§&Λȯ¬VEX3§&Λ§=#0#1S=uSeT

La entrada es una lista de listas y la salida es 1para Truey 0paraFalse

Pruébalo en línea!

Explicación

                      SeT    Create a list with the input and itself transposed
Λ                            Is the following function true for all in the list
 §&                          And the results of the following functions
   Λȯ¬VEX3                     Test for rule 1
          §&                   The and of:
            Λ§=#0#1                Test for rule 2
                   S=u             Test for rule 3

Prueba 1

Λȯ¬VEX3
Λ         Is it True for all ...
   V      Are any of the ...
     X3   Substrings of length 3 ...
    E     All equal
 ȯ¬       Logical not

Prueba 2

Λ§=#0#1
Λ         Is it true for all that ...
 §=       The results of the two functions are equal
   #0         Number of 0s
     #1       Number of 1s

Prueba 3

S=u
S=    Is the result of the following function equal two its argument
  u   Remove duplicates

3

Retina , 129 89 85 bytes

.+
$&,$&
O#$`.(?=.*,)
$.%`
.+
$&;$&
+`(01|10)(?=.*;)

1ms`(.)\1\1|\d,?;|(\D\d+\b).*\2

Pruébalo en línea! Salidas 0 para válido, 1 para inválido. Editar: Guardado 4 bytes gracias a @MartinEnder. Explicación:

.+
$&,$&

Duplicar cada fila con ,separadores.

O#$`.(?=.*,)
$.%`

Transponer el primer duplicado.

.+
$&;$&

Duplicar nuevamente, esta vez con ;separadores.

+`(01|10)(?=.*;)

Elimine todos los pares de dígitos coincidentes que preceden a un punto y coma.

1ms`(.)\1\1|\d,?;|(\D\d+\b).*\2

Verifique si alguna columna o fila falla alguna de las reglas; (.)\1\1busca tres dígitos idénticos seguidos, \d,?;busca un dígito no apareado y (\D\d+\b).*\2busca un duplicado.


Si el propósito de la (...).*última etapa es hacerlo max(matches,1), puede guardar tres bytes utilizando 1en su lugar una configuración.
Martin Ender

Y .\b\d+\bpuede ser \D\d+\b.
Martin Ender

@MartinEnder Originalmente, reemplacé la salida no válida por ninguna salida y la probé al final ... Finalmente lo reduje a una sola prueba al final y me di cuenta de que podía omitir la guía .*que había estado usando anteriormente pero que no pensé usar una configuración para limitar el resultado, gracias!
Neil

3

Pyth , 31 bytes

Muchas gracias a @Leaky Nun .

.Asm++mqy/k\0lQdm<hk3srL8d{Id,C

Verifique todos los casos de prueba o ¡ Pruébelo aquí!


Pyth ,  48 46 44  42 bytes

Esta es la solución inicial.

&{IQ&{I.TQ.Am&q/d\0/d\1!+/d*3\0/d*3\1sC,.T

Verifique todos los casos de prueba o ¡ Pruébelo aquí!

& {IQ & {I.TQ.Am & q / d \ 0 / d \ 1! + / D * 3 \ 0 / d * 3 \ 1sC, .T Programa completo con entrada implícita.

 {IQ ¿La entrada es invariante bajo deduplicación?
& {I.TQ ¿Y su transposición también es invariante?
                                        .TQ Transposición.
                                           Q La entrada.
                                     sC, Comprima el anterior, [^, ^^] (y aplanar)
    ¿Y se cumple la siguiente condición?
          .Am Todos los elementos son verdaderos al mapear sobre ^^.
              q / d \ 0 / d \ 1 Hay tantos 0s como 1s.
             &! + / d * 3 \ 0 / d * 3 \ 1 Y no hay corridas de 3 elementos iguales.

3

MATL , 27 bytes

,G@?!]tEqts~w7BZ+|3<bXBSdvA

La entrada es una matriz que contiene 0y 1. La salida es 0por falsedad, 1por verdad.

Pruébalo en línea! O vea los casos de prueba: 1 , 2 , 3 , 4 , 5 .

Explicación

,       % Do twice. First iteration will use the input, second its transpose
  G     %   Push input
  @     %   Push iteration index: first 0, then 1
  ?     %   If nonzero
    !   %     Transpose
  ]     %   End
  t     %   The top of the stack contains the input or its transpose. Duplicate
  Eq    %   Convert to bipolar form, i.e. replace 0 by -1
  t     %   Duplicate
  s     %   Sum of each column
  ~     %   Negate. If all results are true, condition 2 is fulfilled
  w     %   Swap. Moves copy of bipolar input/transposed input to top
  7B    %   Push [1 1 1], obtained as 7 converted to binary
  Z+    %   2D convolution. Gives a matrix of the same size as the input
  |3<   %   Is each entry less than 3 in absolute value? If all results are true,
        %   condition 1 is fulfilled
  b     %   Bubble up. Moves copy of input/transposed input to top
  XB    %   Convert each row from binary to a number
  Sd    %   Sort, consecutive differences. If all results are nonzero, condition 3
        %   is fulfilled
  v     %   Concatenate all results so far into a column vector
  A     %   True if all entries are nonzero
        % End (implicit). Display (implicit)

2

R , 114107 bytes

-7 gracias a Giuseppe, llamando a las funciones fuera de servicio y realmente comprimiendo las condiciones

function(x)any(f(x),f(t(x)))
f=function(x)c(apply(x,1,function(y)max(rle(y)$l)>2+mean(y)-.5),duplicated(x))

Pruébalo en línea!

Esto solo aplica las reglas a las columnas de la matriz, luego las columnas de la transposición de la matriz.

Toma entrada en el formulario:

matrix(c(0,0,1,1,1,1,0,0,0,1,0,1,1,0,1,0), ncol=4)

Así es como R toma las matrices 2D.

Salidas VERDADERO para fallas, FALSO para pases.



Actualizaciones generales: se utilizan mean(y)-.5dentro de la interna ffunción para obtener los medios en lugar de colMeans, e hicieron gel anonimato. Se añade advertencias para convertir doublea logicalen la llamada a anypero eso está bien.
Giuseppe

@Giuseppe Gracias! ¡Realmente me gusta que se apliquen combinados, un cambio muy inteligente! Lo tuve como 2 aplicaciones separadas en una etapa temprana y no me di cuenta de cuán limpiamente podría combinarlas.
CriminallyVulgar


2

Perl 6 ,100 93 bytes

Cruces FTW! Ahorran 7 bytes.

Por el momento, esto parece estar superando a todas las otras presentaciones escritas en idiomas que no son de golf. Yippie!

{!max (@(.map(*.join)).&{.repeated| |.map:{$_~~/000|111/|.comb(0)-.comb(1)}}for @^a,[Z] @^a)}

Pruébalo en línea!

Explicación : Es un bloque que toma el tablero como una lista de listas. Hacemos una transposición con [Z] @^a(reducir la lista de listas con el operador zip). Entonces, @^a,[Z] @^ahay una lista del tablero y su transposición. Lo recorrimos con lo forque funciona exactamente igual map, solo siendo 1 char más barato en este caso.

En el interior, primero unimos las listas que constituyen filas en cadenas, por lo que tenemos una lista de cadenas en lugar de una lista de listas ( @(.map(*.join))). Luego usamos un bloque anónimo en él ( .&{...}), donde realmente evaluamos las reglas. Los evaluaremos solo en fila. (Ya que lo hacemos para la matriz original y la transposición también).

Para ahorrar bastante !, usamos un poco de lógica y en lugar de probar (NO repeated rows) AND (NO 3 consecutive same symbols) AND (NOT different counts of 0 and 1), probamos NOT[ (repeated rows) OR (3 consecutive same symbols) OR (different counts) ]. Eso es lo que hacemos en el bloque anónimo: .repeatedda todas las filas que ocurren más de una vez, luego mapeamos sobre las filas, tratamos de hacer coincidir 3 símbolos consecutivos usando una expresión regular y restamos los recuentos de 0 y 1. Estos son OR'red con el |. (En realidad, crea una cosa muy poderosa llamada unión , pero no usamos ninguno de sus poderes :)) Después de todo esto, obtenemos una lista de 2 "bools" (uniones sin colapsar). Finalmente o ellos (usando max) y negate ( !), lo que da el resultado deseado.


2

J, 40 38 55 bytes

0=[:([:+/^:_(3(0=3|+/)\"1 ]),:-.@~:,:#=[:+/"1+:@])|:,:]

Pruébalo en línea!

Define una función que toma una matriz cuadrada como entrada.

Al menos está venciendo a Pyth (por ahora ...) (erróneamente). Debería volver a contar los emoji ocultos en mi código, ya que J también se presta bien a eso:

[: /^: :1 |: :] :-.@ :# :@] :~@

Explicación (ligeramente desactualizada)

Esto se ve diferente de mi respuesta, y puedo llegar a actualizarlo. Algunas partes siguen siendo las mismas: simplemente no estaba buscando la regla 3 y no estaba verificando la regla 2 antes.

Dividido en algunas funciones y sin golf:

join_trans  =. |: ,: ]
part_3      =. 3 (0 = 3 | +/)\"1 ]
f           =. 1 - 2 * ]
main        =. 0 = [: ([: +/^:_ part_3 , f) join_trans

unirse_trans

|: ,: ]
|:       Transpose
   ,:    Laminated to
      ]  Input

Esto une la transposición de la matriz a sí misma, creando una matriz de matrices.

parte_3

3 (0 = 3 | +/)\"1 ]
                  ]  Input (matrix and transpose)

Esto verifica la suma de particiones de 3 filas para ver si es 3 o 0 (ya que cualquiera de estos significa una placa inválida), devolviendo 1 si es así y 0 en caso contrario. Funciona tanto en la matriz como en su transposición, ya que le da ambas.

F

1 - 2 * ]

Por falta de un mejor nombre, lo llamo f. Reemplaza los 0 con _1 y deja los 1 sin cambios. Esto es para permitirme verificar eventualmente si el número de 0s y 1s es igual en cada fila y columna (la suma de cada una de las filas debería ser 0).

principal

0 = [: ([: +/^:_ part_3 , f) join_trans
                             join_trans  Join transpose to input
                 part_3 , f              Apply the validity checks and join them
           +/^:_                         Sum until it converges
0 =                                      Equate to 0

Básicamente, lo que aprovechan el hecho de que yo he instalado de manera que f join_transy part_3 join_transambos deben sumar a 0 si y sólo si la junta es válido. part_3debe ser todos ceros para un tablero válido y la totalidad de fdebe sumar cero para un tablero válido, lo que significa que la suma de sus sumas es 0 solo para un tablero válido.


Al menos está ganando a Pyth (por ahora ...). - Realmente necesito jugar mi respuesta
Sr. Xcoder

@ Mr.Xcoder jaja sí, siempre pareces salir adelante, por eso agregué el bit "por ahora". No es que mi respuesta no tenga espacio para jugar golf, simplemente no sé cómo hacerlo demasiado bien.
cole


1
Este código de 33 bytes debe ser equivalente al suyo*/@,@,&(~:,(0~:3|3+/\]),#=2*+/)|:
millas del

2

Haskell , 137 136 127 bytes

¡9 bytes guardados gracias a Lynn!

import Data.List
j=isSubsequenceOf
l x=x==nub x&&and[sum y*2==length x&&not(j[0,0,0]y||j[1,1,1]y)|y<-x]
g x=l x&&l(transpose x)

Pruébalo en línea!


Rodar ambos alls en uno and: l x=x==nub x&&and[sum y*2==length x&&not(j[0,0,0]y||j[1,1,1]y)|y<-x]
Lynn

@ Lynn ¡Gracias! Intenté juntar a esos dos por un tiempo. No sé por qué no pude resolver eso.
Wheat Wizard

1
¿Podrías cambiarte j=isSubSequenceOfa j x=isSubSequenceOf[x,x,x]?
Cyoce

@Cyoce parece perderme un byte. Si tiene una forma de hacerlo que me ahorre un byte, me encantaría implementarlo. La idea parece buena.
Wheat Wizard

En el móvil, hmmm ... ¿Quizás en lugar de j a binvocarlo (y definirlo) como a#b?
Cyoce

2

Java 8, 350 326 325 312 303 299 298 259 255 bytes

int r,z,c,p,i,j,k,d,u,v=1;int c(int[][]b){v(b);k=v-=u=1;v(b);return r;}void v(int[][]b){String m="",x;for(d=b.length;j<d|k<d;k+=u,j+=v,r=m.contains(x)|z!=0?1:r,m+=x)for(x="#",c=0,k*=u,j*=v;j<d&k<d;z+=i|i-1,c*=i^p^1,x+=p=i,r=++c>2?1:r,k+=v,j+=u)i=b[k][j];}

Devuelve 0cuando es un tablero válido; 1si no es válido para una o más de las tres reglas.

-95 bytes gracias a @Nevay .

Explicación:

Pruébalo aquí

int r,z,c,p,i,j,k,d,u,v=1;
                     // Temp integers on class-level

int c(int[][]b){     // Method (1) with int-matrix parameter and int return-type
  v(b);              //  Validate the rows
  k=v-=u=1;          //  Switch rows with columns, and reset `u` to 1
  v(b);              //  Validate the columns
  return r;          //  Return the result
}                    // End of method (1)

void v(int[][]b){    // Separated method (2) with int-matrix parameter and no return-type
  String m="",s;     //  Two temp Strings to validate uniqueness of rows
  for(d=b.length;    //  Set the dimension of the matrix to `d`
      j<d|k<d        //  Loop (1) as long as either `j` or `k` is smaller than `d`
    ;                //   After every iteration:
     k+=u,j+=v       //    Increase the loop-indexes
     r=m.contains(s) //    If we've found a duplicated row,
     |z!=0?          //    or if the amount of zeroes and ones on this row aren't equal
      1:r,           //     Set `r` to 1 (invalid due to either rule 2 or 3)
     m+=s)           //    Append the current row to the String `m`
    for(s=",",       //   Set String `x` to a separator-character
        c=0,         //   Reset the counter to 0
        k*=u,j*=v,   //   Increase the loop-indexes
        j<d&k<d      //   Inner loop (2) as long as both `j` and `k` are smaller than `d`
     ;               //    After every iteration:
      z+=i|i-1,      //     Increase or decrease `z` depending on whether it's a 0 or 1
      c*=i^p^1,      //     Reset `c` if current digit `i` does not equal previous `p`
      s+=p=i,        //     Set previous `p` to current digit, and append it to String `s`
      r=++c>2?       //     If three of the same adjacent digits are found:
         1:r;        //      Set `r` to 1 (invalid due to rule 1)
        k+=v,j+=u)   //      Increase the loop-indexes
      i=b[k][j];     //    Set `i` to the current item in the matrix
                     //   End of inner loop (2) (implicit / single-line body)
                     //  End of loop (2) (implicit / single-line body)
}                    // End of separated method (2)


1

05AB1E , 29 bytes

ø‚D€ÙQIDøì©O·IgQP®εŒ3ù€Ë_P}PP

Pruébalo en línea!

Explicación

Regla 3

ø‚        # pair the input with the zipped input
  D       # duplicate
   €Ù     # deduplicate each
     Q    # check for equality with the unmodified copy

Regla 2

IDøì          # prepend zipped input to input
    ©         # store a copy in register for rule 1
     O        # sum each row/column
      ·       # double
       IgQ    # check each for equality to length of input
          P   # product

Regla 1

®ε            # apply to each row/column in register
  Œ3ù         # get sublists of length 3
     €Ë       # check each if all elements are equal
       _      # logical not
        P     # product
         }    # end apply
          P   # product

Luego tomamos el producto del resultado de las 3 reglas con P


1

Dyalog APL, 64 52 51 49 48 bytes

Requiere ⎕IO←0

{⍲/{(∨/∊⍷∘⍵¨3/¨⍳2)∧((⊢≡∪)↓⍵)∧∧/(≢=2×+/)⍵}¨⍵(⍉⍵)}

Pruébalo en línea!


1

PHP, 245 + 1 bytes

ew esto es voluminoso. los saltos de línea son solo para conveniencia de lectura:

$t=_;foreach($a=($i=str_split)($s=$argn)as$i=>$c)$t[$i/($e=strlen($s)**.5)+$i%$e*$e]=$c;
for(;$k++<2;$s=$t)$x|=preg_match("#000|111|(\d{"."$e}).*\\1#s",chunk_split($s,$e))
|($m=array_map)(array_sum,$m($i,$i($s,$e)))!=array_fill(0,$e,$e/2);echo!$x;

Toma una sola cadena sin líneas nuevas, imprime 1para la verdad, nada para la falsedad.

Ejecutar como tubería -nRo probarlo en línea .

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.