Una cadena de *()[]
llaves se define como una cadena que consiste en los caracteres en los que las llaves coinciden correctamente:
[brace-string] ::= [unit] || [unit] [brace-string]
[unit] ::= "" || "*" || "(" [brace-string] ")" || "[" [brace-string] "]"
Esta es una cadena de llaves válida:
((())***[]**)****[(())*]*
Pero estos no son:
)(
**(**[*](**)
**([*)]**
Su tarea es escribir un programa (o función) que, dado un número entero positivo n
, tome un número como entrada y produzca (o devuelva) todas las cadenas de longitud válidas de llaves n
.
Especificaciones
- Puede generar las cadenas en cualquier orden.
- Puede generar una lista o una cadena separada por un carácter diferente.
- Su programa debe manejar 0 correctamente. Hay 1 posible cadena de llaves de longitud 0, que es la cadena vacía
""
. - Este es el código de golf , por lo que gana la respuesta válida más corta, medida en bytes .
Casos de prueba
0.
1. *
2. ** () []
3. *** ()* []* (*) [*] *() *[]
4. **** ()** []** (*)* [*]* (**) **() **[] *(*) *[*] (()) ()() ()[] ([]) [**] [()] [[]] []() [][] *()* *[]*
code-golf
balanced-string
Fruta Esolanging
fuente
fuente
Respuestas:
Jalea, 29 bytes
-3 bytes gracias a @JonathanAllan
¡Por favor , avísenme si hay problemas / errores / errores o bytes que pueda eliminar!
Pruébalo en línea!
Las soluciones anteriores que tuve:
Explicación (mi mejor intento en una descripción):
fuente
“[(*)]”ṗµḟ”*œṣ⁾()Fœṣ⁾[]FµÐLÐḟ
)Prólogo, 69 bytes
Una de las propiedades más interesantes de Prolog es que en muchos casos es capaz de ejecutar un programa al revés; por ejemplo, en lugar de probar para ver si algo es cierto, puede generar todas las soluciones para las cuales es cierto, y en lugar de verificar la longitud de una cadena, puede generar todas las cadenas con una longitud determinada. (Otra buena propiedad de Prolog es que requiere un espacio en blanco después del final de cada definición de predicado, y se puede insertar una nueva línea tan barata como un espacio; por lo tanto, incluso los programas de golf a menudo son bastante legibles).
Lo anterior define un predicado (el equivalente de una función)
b
que prueba para ver si una cadena tiene una longitud determinada y es una "cadena de llaves" como se define en la pregunta. Específicamente, lo hace a través del soporte de gramática / expresión regular / coincidencia de patrones de Prolog que proporciona algo de azúcar breve y agradable para definir este tipo de expresión (aparentemente esto es estándar / portátil, pero no estaba al tanto de esto mientras escribía originalmente la respuesta, y por lo tanto asumió que la respuesta funcionaría en una sola implementación de Prolog; sin embargo, parece que funciona en cada implementación que cumpla con los estándares). El programa se puede traducir al inglés de manera bastante directa; las primeras dos líneas dicen "una s es una cadena vacía, o una e seguida de una s ; una ees un asterisco, o una s entre paréntesis, o una s entre corchetes ". La tercera línea puede interpretarse como" La b de N puede ser A si A es una lista con una longitud N y A es una s seguida de un nulo cuerda."Tomé un poco de cuidado para escribir
s
(y asíb
) para que coincidan con cada "cuerda tirante" exactamente de una manera (que es la razón por la que tantos
ye
tienen que existir, en lugar de agruparlos en un predicado). Esto los hace a ambos completamente reversibles; por lo tanto,b
se puede usar para generar todas las "cadenas de llaves" de una longitud determinada, además de probar si una cadena es una cadena de llaves de una longitud determinada (también se puede usar en una tercera vuelta, para calcular la longitud de una llave cadena, pero es casi seguro su modo de operación menos útil). La implementación es recursiva, por ejemplo, para generar una s , el código generará todas las e s posibles que no sean más largas que la longitud requerida de la salida, y agregará todas las s posibless que encajan en el espacio restante para ellos; Como especifiqué la longitud del argumento por adelantado (dentro de b ), el motor de Prolog sabe que no puede generar una salida que sea más larga que la longitud dada, lo que permite que la recursión termine.Aquí hay un ejemplo del programa en funcionamiento:
fuente
length
y deappend
cualquier manera es una parte fundamental del lenguaje, y las funciones del usuario a menudo hacen lo mismo.length(A,N)
; siN
se da yA
no se da (lo que sucederá si el predicado se usa de la manera solicitada en el programa),length
generará una lista queA
consta deN
elementos desconocidos. El usolength
para medir la longitud de una lista probablemente se usa más comúnmente (aunque usarlo "hacia atrás" es bastante común en la programación de Prolog). La mayoría de los predicados terminan funcionando de la misma manera (la única razón por la que no lo hacen es si intentar revertirlos construiría un bucle infinito, que es bastante común).-->
y DCG en general son ISO Prolog estándar .Haskell,
10194 bytes¡7 bytes guardados por Zgarb!
Casi directo, siguiendo la definición, pero con el
""
caso movido.Utilizar:
(El segundo cálculo lleva menos de un segundo en una máquina lenta).
También me gustaría compartir el resultado de otro enfoque que se me ocurrió mientras pensaba en generar funciones. Define una lista
b
de listas de cadenas queb!!n
contiene todas las cadenas de llaves de longitudn
. Del mismo modo,u!!n
contiene todos los átomos de tamañon-1
. Una cosa buena es que el código no usa ningún número. No está completamente jugó golf:u
yi
podría ser inline, y ciertamente pierde algunas otras oportunidades de golf. Desafortunadamente, no parece que pueda hacerse más corto que la primera versión, pero se calculalength $ b !! 10
aún más rápido.fuente
b$n-k
yb$n-2
. Además, en la línea final puedes hacera:b<-["()","[]"]
y regresara:s++b
.["()","[]"]
pero no podía ver cómo mejorar el tamaño del código con él. ¡Gracias!Mathematica, 116 bytes
Explicación
Encuentra los caracteres de la cadena
"*([)]"
, dando elList
{"*", "(", "[", ")", "]"}
.Encuentra las tuplas de la lista anterior con longitud
n
.Función booleana sin nombre para determinar si la tupla está equilibrada:
Eliminar todo
"*"
en la entrada.Elimine repetidamente todas las ocurrencias consecutivas de
"("
y")"
o"["
y"]"
hasta que la entrada no cambie.Compruebe si el resultado es un vacío
List
.Encuentra las tuplas que dan
True
cuando se aplica la función booleana.Convierta cada uno
List
de los caracteres enString
s.fuente
{x=a___,"(",")",y=b___}|{x,"[","]",y}
parece funcionar.Python 2, 128 bytes
Atornille expresiones regulares recursivas: ¡estamos usando el analizador sintáctico de Python! Para verificar que, por ejemplo,
*(**[])*
es una cadena de llaves, hacemos lo siguiente:Haga una cadena como
"*", (0,"*","*", [0,0] ,0) ,"*"
, donde cada segundo carácter de cuatro es un carácter de las cadenas de llaves, y los caracteres restantes son pegamento para hacer de esta una posible expresión de Python.eval
eso.Si eso no arroja un error, imprima
s[1::4]
(los caracteres de la cadena de llaves).Los caracteres de pegamento se seleccionan de modo que la cadena que hago sea una expresión de Python válida si y solo si cada segundo carácter de cuatro produce una cadena de llaves válida.
fuente
PHP, 149 bytes
Utiliza el método antiguo generar todo lo posible y luego filtrar. Usar como:
fuente
Python, 134 bytes
repl.it
Función sin nombre que devuelve una lista de cadenas válidas de longitud
n
.Forma todas las
n
tuplas de longitud de los caracteres*()[]
, las une en cadenas usandomap(''.join,...)
filtros para aquellos que tienen corchetes equilibrados eliminando los "pares""*"
y"()"
,"[]"
a su vezn
, comprueba que el resultado es una cadena vacía (eln
tiempo es excesivo, especialmente para"*"
pero es golfista)fuente
Retina , 78 bytes
El recuento de bytes asume la codificación ISO 8859-1.
Pruébalo en línea!
Explicación
Estoy generando todas las cadenas posibles de longitud 5 y luego filtro las inválidas.
Esto convierte la entrada a unario, utilizando
1
como dígito.Esto repetidamente (
+
) reemplaza al primero (1
) uno en cada línea (%
) de tal manera que haga cinco copias de la línea, una para cada carácter posible. Esto se hace usando las sustituciones de prefijos y sufijos,$`
y$'
para construir el resto de cada línea.Este ciclo se detiene cuando no hay más 1s para reemplazar. En este punto tenemos todas las cadenas posibles de longitud
N
, una en cada línea.Estas dos etapas se ejecutan para cada línea por separado (
%
). La primera etapa simplemente duplica la línea, con una;
para separar las dos copias.La segunda etapa es otro bucle (
+
), que elimina repetidamente[]
,()
o*
de la primera copia de la cadena, o elimina un punto y coma al comienzo de la línea (que solo es posible después de que la cadena haya desaparecido por completo).Las cadenas válidas son aquellas que ya no tienen un punto y coma delante de ellas, por lo que simplemente descartamos todas las líneas (
A
) que contienen un punto y coma.fuente
Python 3.5, 146 bytes
Muy largo en comparación con otras respuestas, pero la más corta que pude encontrar actualmente. Tiene la forma de una función lambda anónima y, por lo tanto, debe llamarse en el formato
print(<Function Name>(<Integer>))
Emite un conjunto de Python de desordenados cadenas representan todas las posibles cadenas de llaves de la longitud de entrada.
Por ejemplo, suponiendo que se nombra la función anterior
G
, la invocaciónG(3)
daría como resultado la siguiente salida:¡Pruébelo en línea! (Ideona)
Sin embargo, si, como yo, no eres realmente un fanático de simplificar las cosas usando las funciones integradas, entonces aquí está mi propia respuesta original que no usa ninguna biblioteca externa para encontrar permutaciones, y actualmente está en la friolera de
288237 bytes :Nuevamente, como la respuesta competitiva, esta tiene la forma de una función lambda y, por lo tanto, también debe llamarse en el formato
print(<Function Name>(<Integer>))
Y genera una lista de Python de cadenas sin clasificar que representan todas las cadenas de llaves de la longitud de entrada. Por ejemplo, si se invocara la lambda como
G(3)
, esta vez la salida sería la siguiente:Además, este también es mucho más rápido que mi otra respuesta, pudiendo encontrar todos los corsés de longitud
11
en aproximadamente 115 segundos , los de longitud10
en aproximadamente 19 segundos , los de longitud9
en aproximadamente 4 segundos y los de longitud8
en aproximadamente 0,73 segundos en mi máquina, mientras que mi respuesta competitiva tarda mucho más de 115 segundos para una entrada de6
.¡Pruébelo en línea! (Ideona)
fuente
05AB1E, 23 bytes
Algunas de estas características podrían haberse implementado después de que se publicó la pregunta. Cualquier sugerencia es bienvenida!
Pruébalo en línea!
¿Cómo?
fuente
*
también en la matriz de eliminación? ¿Y podríaõQ
reemplazarse el cheque con algo como NO?'*м„()„[]‚õ:
vs„()„[]‚'*«õ:
(no probado), ya que no hay un comando para concatenar 3 valores AFAIK. El segundo no funcionará, ya que no hay un NO que funcione así en una cadena, AFAIK. (Donde AFAIK representa "hasta donde yo sé")