Escriba un programa o función que tome una cuadrícula de texto rectangular donde cada celda sea una A
o una B
. Todas las A
celdas formarán una forma simplemente conectada , es decir, todas estarán conectadas ortogonalmente sin agujeros (las letras adyacentes en diagonal no cuentan como conectadas). Del mismo modo, todas las B
celdas formarán otra forma simplemente conectada. La cuadrícula siempre contendrá al menos uno A
y al menos uno B
.
Imagine que la cuadrícula es en realidad dos piezas de plástico delgado en forma de bloque, representadas por las porciones A
y B
. Si se colocara plana sobre una mesa, ¿podrían separarse las dos piezas mientras se mantienen ambas completamente planas sobre la mesa?
Imprima o devuelva un valor verdadero si las dos A
y las B
formas se pueden separar de esta manera simplemente separándolas. De lo contrario, imprima o devuelva un valor falso .
Por ejemplo, la entrada
AAA
ABB
AAA
es cierto porque la BB
sección se puede deslizar hacia la derecha, separándola de la A
's:
AAA
A BB
AAA
Sin embargo, la entrada
AAAA
ABBA
ABAA
es falso porque no hay forma de separar las porciones A
y B
sin que se superpongan.
El código más corto en bytes gana. Si lo desea, puede usar cualquiera de los dos caracteres ASCII imprimibles en lugar de A
y B
.
Ejemplos de verdad (separados por líneas vacías)
BBB
BAA
BBB
BA
A
B
AB
AB
AAA
BBB
AAAAB
ABBBB
ABBA
ABBA
AAAA
AAAAAABBBBBBBBB
AABBBBBBBBBBBBB
AAAAAAAAAABBBBB
AABBBBBBBBBBBBB
AAAAAAAAAAAAAAB
AAAAAAAAAAAA
ABABABABABAB
BBBBBBBBBBBB
BAAAAABB
BBAAABBB
BBBABBBB
BBBABBBB
BBBABBBB
BBBBBBBB
BBBBBBBB
AAA
BAA
AAA
Ejemplos de falsa
BBBB
BAAB
BABB
BBBB
BAAB
AABB
BBBBBBB
BBBBBAB
AAAAAAB
BBBBBBB
BAAA
BABA
BBBA
AABA
AAAA
AAAAAAA
ABBBBBA
AAAAABA
BBBBBBA
BAAAAABB
BBAAABBB
BBBABBBB
BBBABBBB
BBBAABBB
BBBBBBBB
BBBBBBBB
AAA
ABA
BBA
ABA
AAA
CJam,
3332201917 bytesVersión revisada, con soporte masivo de @ Sp3000 y @ MartinBüttner:
Pruébalo en línea
Contribuciones
Algoritmo y Prueba
A continuación se explican los criterios para que el rompecabezas se deslice horizontalmente. El caso vertical puede determinarse mirando columnas en lugar de filas, o transponiendo la matriz de caracteres y mirando las filas nuevamente.
Usaré el término "estirar" para una secuencia máxima de las mismas letras. Por ejemplo, las siguientes filas tienen 1, 2 y 3 tramos respectivamente:
También usaré el término "enclavado" para una fila / rompecabezas que no puede separarse.
La observación clave es que el rompecabezas puede separarse si y solo si todas las filas tienen como máximo 2 tramos . O invertido, se enclava si y solo si hay alguna fila con más de 2 tramos .
Lo siguiente podría no calificar como una prueba matemática estricta, pero creo que es una explicación convincente de por qué este tiene que ser el caso.
Es fácil ver que el rompecabezas está enclavado si tiene filas de más de 2 tramos. Mirando una fila con 3 tramos:
Está claro que evita que el rompecabezas se separe porque el
A
tramo está bloqueado entre losB
tramos. Esto significa que la fila está enclavada, lo que a su vez hace que todo el rompecabezas esté enclavado.La dirección opuesta de la prueba no es tan obvia. Necesitamos demostrar que no hay acertijos entrelazados donde todas las filas tengan solo 1 o 2 tramos. Comenzando con un par de observaciones:
A
yB
, el rompecabezas claramente no está enclavado. En este caso, todas lasA
celdas quedan de todas lasB
celdas, o viceversa, y no hay colisiones al separar las dos piezas.El único caso complicado serían los rompecabezas donde tenemos filas con 2 tramos de diferente orden. Voy a mostrar que tales rompecabezas no existen bajo las especificaciones dadas. Para mostrar esto, veamos un rompecabezas parcial que tiene esta configuración, donde
.
están los comodines:Ahora, la especificación dice que tanto el
A
yB
las células se conectan simplemente en todos los puzzles válidos. Para hacer que lasA
celdas se conecten en el rompecabezas parcial anterior, tenemos dos opciones:Damos vueltas alrededor de uno de los tramos de
B
, por ejemplo:Para hacer esto, inevitablemente extendemos una de las filas para tener 3 tramos, por lo que esto nunca nos dará un rompecabezas válido donde todas las filas tengan como máximo 2 tramos.
Los conectamos por un camino directo:
Las
A
celdas ahora están simplemente conectadas y todavía no hay filas con más de 2 tramos. Sin embargo, lasB
células también necesitan estar simplemente conectadas. La ruta directa ahora está bloqueada por lasA
celdas conectadas , y la única forma de conectar lasB
celdas es hacer un bucle alrededor de uno de los tramos de lasA
celdas. Esto nos lleva de vuelta al caso 1, donde no podemos hacer eso sin crear filas de 3 tramos.Para contar los tramos, la implementación utiliza el operador CJam RLE.
Explicación del Código
fuente
JavaScript (ES6),
108107989182 bytesDemostración en vivo . Probado en Firefox. Toma la entrada como una cadena delimitada por nueva línea.
Ediciones:
\n
a una nueva línea literal.g
función y llamando a RegExp directamente en la matriz en lugar de usarfind
.Cómo funciona
Versión previa:
a
y divídala por nuevas líneas en una serie de cadenas.a
y almacenar enT
. Usemap
para iterar sobre cada elemento dea
, divida la cadena en una matriz de caracteres, y usemap
nuevamente para agregar eli
carácter th en la línea a lai
línea th deT
. Como cada elemento deT
no está inicializado, terminará pareciendo algo así"undefinedAAABBA"
, pero esto no importará.g
que coincida con el patrón/AB+A|BA+B/
. Si coincide, las piezas se bloquean en la dirección dada porque entonces hay un conjunto deB
s intercalados entre dos o másA
so o viceversa.g
de prueba para probar todos los elementos del bloquea
y su transposiciónT
para una coincidencia usandofind
. Si ambos coinciden, las piezas se bloquean en ambas direcciones, por lo que se genera un valor falso, de lo contrario, uno verdadero.fuente
Javascript (ES6), 118
Explicación:
fuente
JavaScript (ES6) 72
74Editar 2 bytes guardados gracias a @NotthatCharles
Tengo la comprensión intuitiva de que si una pieza puede deslizarse solo una fracción de paso, entonces es gratis. Los casos de prueba actuales confirman esto.
Así que verifico solo un paso en cada dirección.
Caracteres utilizados: 1 y 0
2 bytes más para usar 2 caracteres imprimibles como A y B
Pruebe a ejecutar el fragmento a continuación en un navegador compatible con EcmaScript 6 (compatible con el operador de propagación: IE Firefox)
fuente
s[p+o]=='0'
Parece un poco largo. ¿Podría ser reemplazado con1-s[p+o]
, o al menoss[p+o]==0
?=='A'
puede ser sustituido por<'B'
. Lo mismo para=='B'
x+s[p+o]=='AB'
?Mathematica
10069 bytesCon 31 bytes masivos guardados, gracias a @Martin Buttner,
Formatea la entrada como una matriz de caracteres; También hace una transposición de la matriz. Si la matriz o su transposición no tiene más de 2 corridas por fila, entonces el rompecabezas puede deslizarse.
{a,a,b,b,b}
Tiene 2 corridas de letras.{a,a,b,a,a}
Tiene 3 corridas de letras.{a,a,b,a,a,a,b,b,b,b,b,b,b,b}
Tiene 4 corridas de letras.fuente
Dyalog APL, 22 bytes
Pruébalo aquí Esta es una función que toma una matriz 2D de caracteres y devuelve
1
las instancias deslizantes y las0
no deslizantes. El algoritmo es similar a la mayoría de las otras respuestas: verifique la matriz y su transposición de que ninguna fila contenga más de un par adyacente de letras diferentes. Para la matriz de entrada 4x3la función se puede invocar como
que da como resultado
1
.Explicación
fuente
JavaScript (ES6), 94 bytes
Método alternativo del mismo tamaño:
Esto regresa
1
para una entrada veraz y0
falsa. Empecé a trabajar en esto antes de que se publicaran otras respuestas. Originalmente también intenté usar las comprensiones de matriz de ES7, pero eso terminó aproximadamente 10 caracteres más que este método.Pruébalo:
Sugerencias bienvenidas!
fuente