Antecedentes
En Bejeweled y juegos similares, el jugador debe intercambiar dos gemas adyacentes (sin diagonales) en una cuadrícula de gemas de 8x8 para que coincida con tres del mismo color en una fila. Las gemas se pueden combinar horizontal o verticalmente. La jugabilidad continúa hasta que no exista ningún movimiento que pueda realizarse, lo que resulta en tres seguidos, momento en el cual el juego termina.
Tarea
El objetivo es escribir un programa que determine si un juego de Bejeweled aún no ha terminado. En otras palabras, debe verificar para ver si hay un posible movimiento que haga al menos tres seguidos. Puede haber más de tres gemas seguidas y sigue siendo un movimiento válido.
Entrada
Su programa debe aceptar mediante entrada estándar una representación 8x8 de una cuadrícula Bejeweled. Cada uno de los siete colores de gemas estará representado por un dígito del 1 al 7. Cada línea contendrá una fila y se ingresarán 8 líneas, cada una con 8 dígitos. Ver los ejemplos. Puede suponer que la entrada siempre seguirá este formato y nunca contendrá tres seguidas.
Salida
Luego, el programa debe generar (a la salida estándar) yes
o no
dependiendo de si existe o no al menos un movimiento válido que resulte en tres o más gemas seguidas. Su programa no debe generar nada más que una sola instancia de yes
o no
.
Reglas
Su programa no debe usar ningún archivo o recurso externo, argumentos de línea de comandos o requerir un nombre de archivo determinado. El programa con el menor número de bytes en su código fuente gana.
Ejemplos
Entrada:
12314131
13224145
54762673
61716653
61341144
23453774
27645426
75575656
Salida: yes
Entrada:
35261546
76421754
15743271
62135642
35617653
64565476
54427254
15635465
Salida: no
Consulte la respuesta de MT0 a continuación para ver casos de prueba adicionales.
Respuestas:
Solución original: JavaScript -
261255228227179153 caracteresSuponiendo que la cadena a probar está en la variable
s
(para que sea una función,f
luego agreguef=s=>
al comienzo del código o, de lo contrario, tome la entrada de un indicador y luego reemplaces
conprompt()
).Las salidas son a la consola.
3 RD Solución: JavaScript (ECMAScript 6) - 178 caracteres
Tomé la segunda solución, a continuación, (que usa expresiones regulares para verificar los caracteres en ciertas configuraciones) y la modifiqué para verificar la cadena de caracteres idénticos en las mismas configuraciones sin usar expresiones regulares.
La cadena Base-36
"2313ab1b8a2a78188h9haj9j8iaiir9r"
proporciona pares de desplazamientos para verificar, es decir, el par23
da como resultado la comprobación de si el carácter i th es idéntico al carácter (i + 2) th y al carácter (i + 3) th (el equivalente de la expresión regular(.).\1\1
- con algunas comprobaciones adicionales para garantizar que el carácter no idéntico no sea una nueva línea).2 nd Solución: JavaScript (ECMAScript 6) - 204 caracteres
Crea múltiples expresiones regulares (ver más abajo para más detalles) usando pares de valores tomados de la cadena Base-18
10907160789879h8
y tomaOR
todas las pruebas. Para reducirlo aún más, puede observar que las expresiones regulares vienen en pares donde una es la "inversa" de la otra (ignorando las expresiones regulares para 3 en una fila horizontal y verticalmente ya que el OP indica que nunca estarán presentes) si desea agregar esas pruebas nuevamente en el anexo0088
a la cadena Base-18).Explicación
Comience con 16 expresiones regulares que cubren todas las configuraciones posibles de movimientos válidos:
( Nota: las expresiones regulares para 3 en una fila horizontalmente ( 0º ) y verticalmente (parte del noveno ) son irrelevantes ya que el OP establece que las entradas que coincidan con estas nunca estarán presentes ) .
Probar cada uno de ellos contra la entrada determinará si se puede encontrar un movimiento válido de esa configuración.
Sin embargo, las expresiones regulares se pueden combinar para dar estos 6:
Estos se pueden combinar en una sola expresión regular:
Que solo necesita ser probado contra la entrada.
Casos de prueba
Algunos casos de prueba que otras personas pueden encontrar útiles (no cumple con el formato de entrada de usar solo los dígitos 1-7, pero eso se corrige fácilmente y es solo una cuadrícula de 8x4, ya que es el mínimo requerido para una prueba de todas las entradas válidas )
En el formato de un mapa desde la cadena de entrada a cuál de las 16 expresiones regulares anteriores coincide.
Editar 1
Reemplazar
\d
s con.
: guarda 6 caracteres.Editar 2
Reemplace
(?:.|\n)
con[\s\S]
y elimine grupos no capturadores adicionales y referencias de respaldo actualizadas (como lo sugiere m-buettner ) y agregue en la salida sí / no.Editar 3
Editar 4
Se agregó otra solución (más corta) y dos casos de pruebas no coincidentes más.
Editar 5
Editar 6
fuente
?'yes':'no'
recuento en su personaje para ser justos, porque está en los requisitos y todos los demás lo están usando..
que coincida con cualquier personaje, incluida la nueva línea Con Perl, la expresión regular combinada es solo una cadena de 129 bytes (que, siendo flojo, compilé con Regexp :: Assemble ), por lo que todo el programa Perl tiene aproximadamente 150 bytes..{8}|.{9}
con.{8,9}
y.{7}|.{8}
con.{7,8}
Python 383
¡Solo una línea * de Python!
* Bueno, con punto y coma, pero eso todavía no es trivial en Python (¡las frases de Python son divertidas! )
fuente
Node.js - Solución ingenua - 905 bytes
Bueno, todavía no hay respuestas, así que publicaré una solución realmente ingenua en Node.js
Realiza todos los movimientos posibles y luego prueba el tablero resultante para ver si hay 3 seguidos.
Golfé (con el compilador de cierre de Google) (algunas cosas extrañas como! 0 y! 1; ni siquiera estoy seguro de lo que hizo con mi intercambio XOR)
Tenga en cuenta que escribí todo esto en mi móvil y no tengo tiempo para probarlo ni nada. Comenta si ves algún error, lo comprobaré yo mismo más tarde.
La versión legible humana pre golf
fuente
Perl,
11496959392878685 bytesIncluye + para
-a0p
Ejecutar con la entrada en STDIN:
bejeweled.pl
:Esto combina una solución de expresión regular horizontal de una sola dirección con rotaciones
Explicación:
En esta solución, rotaré repetidamente y haré las siguientes 4 pruebas:
Dónde
\C
está "cualquier personaje" (a diferencia de.
esto incluye nueva línea). Excepto que\C
está en desuso y da lugar a advertencias, por lo que uso\H
(espacio no horizontal) en su lugar, que es lo suficientemente bueno como para capturar todos los dígitos y la nueva línea.Después de 4 rotaciones, esto habrá realizado las 16 pruebas necesarias
fuente
Python3, 314B
Cambie el 8, el 5 en la línea 6 y los 8 en la línea 9 para manejar tamaños de entrada arbitrariamente grandes; tampoco le importa cuál es cada valor, por lo que puede alimentarlo:
y volverá
yes
.Anotaciones
fuente
GNU sed 255 + 2 = 257B
Pensé que esto no iba a ser tan bueno como Python, pero ahora es: - / He estado sin acceso a Internet hoy, así que me ocupé de resolver esto en sed :). Debe llamarse con la bandera -r, es decir
sed -rf command.sed < input
, agregué 2 a mi puntaje.Cómo funciona:
fuente
Ruby, 201 bytes
Me decepcionó no ver ninguna solución a este gran desafío que no utiliza una expresión regular o fuerza bruta (aunque son geniales), así que escribí una. Toma entrada en STDIN.
El algoritmo aritmético a nivel de bit se deriva de esta fantástica respuesta en Game Development Stack Exchange de @leander.
Ruby lambda, 181 bytes
Aquí es como una lambda que toma una cadena y devuelve
true
ofalse
:Véalo en repl.it: https://repl.it/ColJ/2
Sin golfos y explicación
El código itera sobre los dígitos "1" a "9." Cada iteración tiene dos pasos discretos:
El primer paso es la transformación de la placa, que puede ver en el
s.scan(n)
bloque en el código no protegido. Transforma el tablero en una matriz de 8 enteros, uno para cada fila, tratando los dígitos coincidentes como 1 y todos los demás como 0 en una cadena binaria. Por ejemplo, toma la fila12231123
. En la primera iteración, esto se convertirá en la cadena binaria10001100
(todos los 1 se convierten en, er, se quedan 1 y todos los demás dígitos se convierten en 0), que es el número decimal 140. En la segunda iteración, la misma fila se convierte01100010
(los 2 se convierten en 2 y todos los demás dígitos se convierten en 0), o decimal 98.Simultáneamente realiza una segunda transformación, que es la misma que la primera pero con el tablero girado 90 grados. Esto nos permite usar la misma lógica para hacer coincidencias horizontales que verticales. Para simplificar, concatena las dos tablas en una sola larga con un cero al principio, en el medio (para separar las dos tablas) y al final para el relleno.
El segundo paso es buscar posibles coincidencias, que puedes ver en el
each_cons(3).any?
bloque. Las filas transformadas (que ahora son enteros de 8 bits) se verifican en grupos (superpuestos) de tres filas ( x , y , z ) utilizando aritmética bit a bit. Cada grupo se verifica para ver si se puede hacer una coincidencia en la fila y , ya sea cambiando una pieza en la fila y o cambiando una pieza a y desde x o z . Como hay una "fila" cero antes y después de las filas de los tableros originales y rotados, no tenemos que verificar si estamos en la primera o última fila de un tablero.Si no se encontraron coincidencias, continúa con la siguiente iteración.
fuente