¿Están los soportes completamente combinados?


56

Debe escribir un programa o función que tome una cadena de corchetes y genere si esa cadena coincide o no completamente. Su programa debe imprimir un valor verdadero o falso , y IO puede estar en cualquier formato razonable .

Reglas y definiciones:

  • A los efectos de este reto, un "soporte" es cualquiera de los siguientes caracteres: ()[]{}<>.

  • Un par de paréntesis se considera "coincidente" si los paréntesis de apertura y cierre están en el orden correcto y no tienen caracteres dentro de ellos, como

    ()
    []{}
    

    O si cada subelemento dentro de él también coincide.

    [()()()()]
    {<[]>}
    (()())
    

    Los subelementos también se pueden anidar en varias capas de profundidad.

    [(){<><>[()]}<>()]
    <[{((()))}]>
    
  • Una cadena se considera "Totalmente coincidente" si y solo si:

    1. Cada personaje es un paréntesis,

    2. Cada par de soportes tiene el soporte de apertura y cierre correcto y en el orden correcto, y

    3. Cada soporte se corresponde.

  • Puede suponer que la entrada solo contendrá ASCII imprimible .

Prueba IO

Aquí hay algunas entradas que deberían devolver un valor verdadero:

()
[](){}<>
(((())))
({[<>]})
[{()<>()}[]]
[([]{})<{[()<()>]}()>{}]

Y aquí hay algunas salidas que deberían devolver un valor falso:

(               Has no closing ')'
}{              Wrong order
(<)>            Each pair contains only half of a matched element
(()()foobar)    Contains invalid characters
[({}<>)>        The last bracket should be ']' instead of '>'
(((()))         Has 4 opening brackets, but only 3 closing brackets.

Como de costumbre, este es el código de golf, por lo que se aplican las lagunas estándar y gana la respuesta más corta en bytes.



77
Nota para posibles votantes cercanos: el desafío que vinculé también incluye un orden de prioridad para los tipos de paréntesis, por lo que no pueden anidarse en un orden arbitrario. Creo que eso lo hace lo suficientemente diferente.
Martin Ender

Es [}un partido? Y si no, ¿dónde está excluido por estas reglas?
user207421

2
@EJP No, no lo es. Each pair of brackets has the correct opening and closing bracket and in the right order.
DJMcMayhem

66
Votaré la primera solución entre paréntesis
leo

Respuestas:


17

05AB1E , 19 bytes

La entrada se da entre comillas . Código:

"[](){}<>"2÷)"":g2Q

Bueno, mierda, se encontraron muchos errores y características no implementadas. Explicación:

"[](){}<>"           # Push this string
          2÷         # Split into pieces of two
            )        # Wrap it into an array (which should not be needed)
             ""      # Push an empty string
               :     # Infinite replacement

Esta es en realidad una parte difícil. Lo que se ve en pseudocódigo es:

input().replace(['[]', '()', '{}', '<>'], "")

Esto está cubierto por esta parte del código 05AB1E :

if type(b) is list:
    temp_string = temp_string_2 = str(a)
    while True:
        for R in b:
            temp_string = temp_string.replace(R, c)
        if temp_string == temp_string_2:
            break
        else:
            temp_string_2 = temp_string
    stack.append(temp_string)

Como puede ver, este es un reemplazo infinito (hecho hasta que la cadena ya no cambie). Por lo tanto, no tengo que preocuparme por configurar el reemplazo en un bucle, ya que esto ya está incorporado. Después de esto:

                g    # Take the length of the final string
                 2Q  # Check if equal with 2 (which are the quotes at the end)

Utiliza la codificación CP-1252 . Pruébalo en línea! (ligeramente modificado porque la versión anterior está en desuso).


1
Muy bien golfizado!
SamyQc

1
¿Fue esto antes de que õse agregara?
Zacharý

@ Zacharý Sí, eso es correcto
Adnan

33

Brain-Flak , 1101, 1085 , 981 bytes

{(<(({}))((((()()()()()){}){}){})({}[{}]<(())>){((<{}{}>))}{}>{({}<>)(<>)}{}<(({
}))((((()()()()()){}){}){}())({}[{}]<(())>){((<{}{}>))}{}>{({}<>)({}[{}](<()>)){
{}{}(<(())>)}{}{<>{{}}<>{{}}((<()>))}{}(<>)}{}<(({}))(((((()()()()()){}){})){}{}
)({}[{}]<(())>){((<{}{}>))}{}>{<({}()<>)>()(<>)}{}<(({}))(((((()()()()()){}){})(
)){}{})({}[{}]<(())>){((<{}{}>))}{}>{<({}()<>)>()({}[{}](<()>)){{}{}(<(())>)}{}{
<>{{}}<>{{}}((<()>))}{}(<>)}{}<(({}))((((()()()){}){}()){({}[()])}{})({}[{}]<(()
)>){((<{}{}>))}{}>{<({}()()<>)>()(<>)}{}<(({}))((((((()()()()()){})){}{}())){}{}
)({}[{}]<(())>){((<{}{}>))}{}>{<({}()()<>)>()({}[{}](<()>)){{}{}(<(())>)}{}{<>{{
}}<>{{}}((<()>))}{}(<>)}{}<(({}))((((((()()()()()){}){}){}())){}{})({}[{}]<(())>
){((<{}{}>))}{}>{<({}()()()<>)>()(<>)}{}<(({}))((((((()()()()()){}){}){}())()){}
{})({}[{}]<(())>){((<{}{}>))}{}>{<({}()()()<>)>()({}[{}](<()>)){{}{}(<(())>)}{}{
<>{{}}<>{{}}((<()>))}{}(<>)}{}<{}>[()]){<>{{}}(<()>)<>{{}}(<()>)}{}}<>([]<>)({}<
(())>){((<{}{}>))}{}

Pruébalo en línea!

Esto es 980 bytes de código fuente, y +1para el -aindicador que permite la entrada ASCII (pero la salida decimal)

Esta es una respuesta que he querido escribir durante mucho, mucho tiempo. Al menos 6 meses. Esperé para publicar esto porque sabía que responder a este desafío sería muy difícil en ataques cerebrales. Pero vale la pena por una razón muy importante: el código fuente en sí mismo es una entrada verdadera, que es el punto central de este lenguaje.

Y mientras escribía sobre esto , esta pregunta fue lo que me inspiró a escribir cerebro-flak.

Poco después de que escribí ¿Los corchetes coinciden completamente? Me hizo preguntarme cuánta información puede almacenar con solo corchetes coincidentes. Una cosa que me llamó la atención fue que a pesar de que solo tienes 4 tipos de "átomos":

(){}[]<>

realmente tiene 8 unidades de información para transmitir, ya que cada uno de estos tipos de paréntesis puede estar vacío o tener otros paréntesis intermedios, que son piezas de información fundamentalmente diferentes. Entonces, decidí escribir un idioma que solo permitiera paréntesis, y donde los paréntesis vacíos transmiten algo diferente de los paréntesis con otros paréntesis dentro de ellos.

Esta respuesta tardó aproximadamente dos horas en escribirse. Admito que está bastante mal, sobre todo porque se repite gran parte del código para cada tipo de soporte. Pero estoy asombrado de haber podido escribir una respuesta, especialmente dado que Brain-Flak es

Un esolang minimalista diseñado para ser doloroso de usar

Voy a intentar jugar golf más tarde, pero quería sacar esto de todos modos.

Tengo una explicación detallada, pero tiene aproximadamente 6 mil caracteres, así que creo que no sería prudente pegar todo en esta respuesta. Puedes leerlo aquí si quieres. Agregaré una explicación más corta aquí.

La idea básica es que repetimos los siguientes pasos para cada personaje en la pila:

  • Verificamos cada personaje para ver si coincide con algún paréntesis. Si se trata de un paréntesis de apertura, insertamos un número en la otra pila de acuerdo con la siguiente asignación:

    ( = 1
    < = 2
    [ = 3
    { = 4
    
  • Luego verificamos si coincide con algún soporte de cierre. Si lo hace, empujamos el número equivalente en la pila alternativa, al igual que para abrir paréntesis. Luego , verificamos si los dos números superiores son iguales. Si lo son, los dos aparecen y el programa continúa de manera normal. Si no lo están, limpiamos ambas pilas (para detener el bucle) y empujamos una en la pila alternativa. Esto es esencialmente una declaración de "ruptura".

  • Después de verificar los 8 tipos de paréntesis, empujamos el valor de esta ejecución a través del ciclo. Como ponemos a cero la mayor parte, los únicos fragmentos que tienen algún valor son los condicionales cuando los comparamos con los corchetes. Entonces, si cualquier paréntesis coincide, el ciclo completo tiene un valor de 1. Si ninguno de ellos lo hizo, el ciclo completo tiene un valor de 0. En este caso, borraremos ambas pilas y colocaremos un 0 en la pila alternativa. Nuevamente, esto es como una declaración de "descanso".

Después de que se ejecuta este bucle principal, el resto es bastante simple. Estamos en la pila principal (vacía), y la pila alternativa está vacía (si los paréntesis coincidieron) o no vacía si no lo estaban. Entonces ejecutamos esto:

#Toggle to the alternate stack
<>

#Push this stack-height onto main-stack
([]<>)

#Logical not
({}<(())>){((<{}{}>))}{}

Esto empujará un 0 o un 1 a la pila principal, y cuando el programa finalice, se imprimirá implícitamente.



revisiones

  • Se eliminó algo de redundancia push pop

  • Cambié mi lógica de contador cero


1
Awwwwwweeeeesommmmeeeee!
Arjun

23

Cerebro-Flak , 204 196 190 bytes

{({}<>)<>((((()()()()()){})(({}){})())({}(({})((({}){})(<()>))))())(({<({}<>[({})])>[()]{()(<{}>)}{}<>}{}()<({}<>[({})]){(<{}({}())>)}{}<>>)){(<({}{}<>[{}]{}<>)>)}{}{<>{{}}}{}}<>((){[()]<>})

Pruébalo en línea!

-8 bytes gracias al asistente de trigo. -6 bytes gracias a Jo King.

Explicación

Este programa almacena los códigos de caracteres de todos los corchetes no cerrados actuales en la segunda pila. Los pares de soportes <>, []y {}cada uno tiene los códigos de caracteres que difieren en exactamente 2, así que no hay necesidad de comprobar específicamente para ellos. El par ()solo difiere en 1, por lo que verificamos (específicamente y disminuimos efectivamente ese byte (en realidad incrementamos cada dos bytes) antes de continuar.

# While there are bytes left to process
{

 # Move byte to second stack
 ({}<>)<>

 # Push 40, 0, 40, 60, 91, 123: (, then null, then all four opening brackets
 ((((()()()()()){})(({}){})())({}(({})((({}){})(<()>))))())

 ((

   # For each opening bracket type:
   {

    # Evaluate as zero
    <

     # Compute difference between bracket type and input byte
     ({}<>[({})])

    >

    # Evaluate loop iteration as -1 if equal, 0 otherwise
    [()]{()(<{}>)}{}<>

   }

   # Remove the 0 that was inserted to terminate that loop
   {}

   # Add 1 to result
   ()

   # Evaluate rest of this expression as zero
   <

    # Determine whether the byte is open parenthesis
    ({}<>[({})])

    # If not:
    {

     # Add 1 to byte and break if
     (<{}({}())>)

    }{}

    # Return to main stack
    <>

   >

 # Push result twice (0 if matched an opening bracket, 1 otherwise)
 ))

 # If byte was not an opening bracket:
 {

  # Push zero to break out of if
  (<

    # Push (open bracket + 2 - byte) below that zero
    ({}{}<>[{}]{}<>)

  >)

 }{}

 # If byte was neither an opening bracket nor the appropriate closing bracket:
 {

  # Clear alternate stack and stay there to break out of main loop early
  <>{{}}

 }{}

# End of main loop
}

# If a prefix was invalid, the top of the other stack is the same nonzero value
# that made us break out in the first place. If the string was a valid prefix,
# the other stack contains every unclosed bracket.  If the string is balanced,
# there are none of these. Thus, the other stack is empty if the
# brackets are balanced, and has a nonzero value on top otherwise.

# Push 1 on other stack if empty, and 0 on current stack otherwise
<>((){[()]<>})

"lógico no de diferencia" (también conocido como iguales) podría ser más corto como([{}]<>({}))((){[()](<{}>)}{})
Wheat Wizard

Creo que puede reemplazar esa última verificación con ({<>[()]}())-6 bytes
Jo King

@JoKing Gracias. No creo haberlo visto nunca.
Nitrodon el

Sí, lo descubrí en mi propia respuesta y me di cuenta de que también era aplicable a la tuya
Jo King

13

JavaScript (ES6), 52 50 bytes

f=s=>(t=s.replace(/\(\)|\[]|{}|<>/,''))==s?!s:f(t)

Quite los corchetes repetidamente hasta que el resultado sea el mismo que el original, luego devuelva falso a menos que la cadena esté ahora vacía.

Editar: Guardado 2 bytes gracias a @ edc65.



11

CJam, 25 24 23 21 bytes

Gracias a Sp3000 por guardar 2 bytes.
Gracias a jimmy23013 por guardar 2 bytes.

q_,{()<>}a`$2/*{/s}/!

Banco de pruebas.

Trabaja esencialmente el mismo que el otro responde: nos quitamos repetidamente (), [], <>y {}de la cadena y comprobar si terminamos con la cadena vacía. Para evitar tener que verificar cuando hayamos terminado, eliminamos los pares de Nveces donde Nestá la longitud de la cadena, que siempre es suficiente (ya que cada iteración eliminará al menos dos caracteres, a menos que hayamos terminado). Me alegra ver que esto no supera a Retina. :) (Aunque Pyth o Jelly podrían ...)

Aquí hay un truco divertido de golf: para obtener la cuerda ()<>[]{}usamos lo siguiente:

{()<>}a`$

El, {()<>}es solo un bloque (es decir, una función), que contiene los otros corchetes como código. Con aenvolvemos el bloque en una matriz. El `stringifica esa matriz, que da "[{()<>}]". Finalmente, clasificamos la cadena con $, que reorganiza los corchetes ()<>[]{}.


No estoy familiarizado con su idioma, pero su descripción de su truco de golf hace que parezca ()<>[]{}`que funcionaría igual de bien y tendría la misma cantidad de bytes, ¿verdad?
Mooing Duck el

1
@MooingDuck No porque ()<>hay cuatro operadores (decremento, incremento y luego comparación o truncamiento según los operandos), que se ejecutarían de inmediato, mientras que {}denota un bloque (el equivalente de CJam de una función), es decir, un fragmento de código que se acaba de insertar en la pila sin evaluarlo de inmediato. Es por eso que necesito {}ajustar el ()y <>, pero luego usarlo apara poner todo en una matriz es más corto que [...].
Martin Ender

10

Python, 67 bytes

lambda s:eval("s"+".replace('%s','')"*4%([],(),{},'<>')*len(s))==''

Genera y evalúa una expresión que se parece a

s.replace('[]','').replace('()','').replace('{}','').replace('<>','').replace('[]','').replace('()','').replace('{}','').replace('<>','')

y comprueba si el resultado está vacío.

Sp3000 ahorró 8 bytes al señalar que [],(),{}se pueden subtitular sin comillas porque son objetos de Python y que dos parens no eran necesarios.


8

Yacc, 119 bytes

No utiliza regex / replace.

%%input:r;r:%empty|'['r']'r|'{'r'}'r|'('r')'r|'<'r'>'r;%%yylex(){return getchar();}main(){return yyparse();}yyerror(){}

Sin golf

%%                              # Grammar in BNF
input:
  r;
r:
  %empty
| '['r']'r
| '{'r'}'r
| '('r')'r
| '<'r'>'r;
%%                              # Minimal parser invocation and lexer
yylex(){return getchar();}
main(){return yyparse();}
yyerror(){}

Compilacion

yacc -o bracket.c bracket.y
cc -o bracket bracket.c

Uso

~/ % echo -n "<()[]>" | ./bracket
~/ %
~/ % echo -n "{" | ./bracket
~/ 1 %                                                                         :(

7

Pyth, 31 25 24 bytes

Golfed hasta 25 bytes gracias a FryAmTheEggMan Eliminado 1 byte

VQ=:Q"<>|\[]|{}|\(\)"k;!

Pruébelo aquí: ¡ conjunto de pruebas !

Todavía soy un novato Pyth, cualquier ayuda es apreciada.

Explicación

VQ                         For N in range(0, len(z)), with Q being the evaluated input.
                           Optimal solution would be to use range(0, len(z)/2) instead, but it add two bytes.
  =:Q"<>|\[]|{}|\(\)"k     assign Q without {}, [], <> nor () (regex replacement) to Q
                      ;    End of For loop
                       !   Logical NOT of Q's length (Q is the input, but has gone several times through y, and Q is implicit).
                           This last operation returns True if len(Q) is 0 (which means all brackets were matched), False otherwise

Por cierto, felicidades a la otra respuesta Pyth (que actualmente es de 20 bytes)


¡Bienvenido a Programming Puzzles y Code Golf!
Adnan

@Adnan Gracias! Este es mi primer golf!
FliiFe

Bonito primer golf! Con un cierto cambio y esas cosas, se puede llegar a 25: Vz=:z"<>|\[]|{}|\(\)"k;!z. Particularmente notable, básicamente nunca necesita usarlo lsi realmente no necesita el número, y =adivina automáticamente la primera variable utilizada en una expresión. Avíseme si desea que le explique algo más en la sala de chat de Pyth :)
FryAmTheEggman

@FryAmTheEggman ¡Gracias! No sabía que lera innecesario, es bueno saberlo. Al principio, declaró una función porque mi lógica era diferente, y olvidé eliminarla. ¿Debo incluir tu respuesta a la mía? (Soy un novato>. <)
FliiFe

3
En general, si está publicado en un comentario, el autor del comentario quiere que lo use. ¡Así que adelante! :)
FryAmTheEggman

6

Pyth, 20 bytes

!uuscNTc"[](){}<>"2G

Pruébelo en línea: Test Suite

Repetidamente elimina las apariciones de [], (), <>y {}por la división y la re-fusión. Comprueba si la cadena resultante está vacía o no.


4

Javascript ES6, 54 bytes

f=_=>_.match(x=/\(\)|\[]|{}|<>/)?f(_.replace(x,'')):!_

Utiliza una implementación recursiva de reemplazo. Suficientemente simple.



4

Perl, 34 33 bytes

Incluye +2 para -lp

Ejecutar con entrada en STDIN:

./brackets.pl <<< "{<>()}"

brackets.pl:

#!/usr/bin/perl -lp
s/\(\)|\[]|<>|{}//&&redo;$_=!$_

Encuentra el primer par de paréntesis sin nada entre ellos y lo elimina siempre que haya alguno. Luego verifica si la cadena final está vacía.


No s/\(\)|\[]|<>|{}//&&redo;$_=!$_funcionaria? :)
Dada

Sería genial si puedes dar una explicación también.
Prashant Pokhriyal

@Dada Por supuesto. Debo estar poniéndome senil ...
Ton Hospel

4

Brain-Flak , 204 bytes

(()){{}{({}<>)<>}<>({<(<(({})<>)>)(((((((([(())()()()]){}){}){}())(()))(((())()){}()){})){})(({<(({}<>{}[()]))>(){[()](<{}>)}{}<>}{}))<>{}<>{{}({}[({})]<>({})){(<>)(<>)}{}{}(<>)}{}>{}<>}<>)}{}((){<>[()]})

Pruébalo en línea!

No es tan corto como la respuesta de Nitroden , pero utiliza un enfoque muy diferente. Éste se ejecuta a través de la entrada repetidamente, eliminando pares de corchetes adyacentes cada vez hasta que no quede ninguno. En ese punto, si queda algo en la pila, entonces la cadena no coincidía completamente.

Explicación:

(())  Push 1 to simulate the check at the start of the loop
{  While check
	{}           Pop check
	{({}<>)<>}<> Reverse input
	({           Loop over input
		< Don't push the values of these calculations
		(<(({})<>)>)  Create a copy of the top of the input and push to the other stack
		(((((
		((([(())()()()]){}){}){}())
		(()))
		(((())()){}()){})
		){})          Push the differences in values of the end brackets 
		(({<(({}<>{}[()]))>(){[()](<{}>)}{}<>}{}))  If the copy is the same as any of these, push the difference between the other bracket twice
		<>{}<>  Pop copy
		{  If this character is a start bracket
			{}({}[({})]<>({}))  Check if the next character is the end bracket
			{(<>)(<>)}{}          If not, push a 0 to each stack as buffer
			{}       Pop the top of the input stack, either the start bracket if they matched or the buffer 0
			(<>)     Push 0 to other stack to end check
		}{}>
		{}   Pop the top of the other stack
		         If the character was not an end bracket, pop the copy of check, which is 0
		         If it was, but didn't match the next character, pop the buffer 0
		         If the brackets matched, pop the end bracket and add it to the loop total
	<>}	Repeat with the rest of the input
	<>)	Push the loop total
		If any brackets were matched, the loop total is non zero
}{}
((){<>[()]}) If there is anything left on the stack, push 0 to the other stack, otherwise push 1

3

Brainfuck, 132 bytes

+>,[[<->>+>[-]<<-]<[>+>[<+<+>>>+<-]+++++[>--------<-]>[<<+>++++[>-----<-]>[<++++
+[>------<-]>-[<++++[>--------<-]>[,>]]]]<],]<<[>]>.

Formateado:

+>,
[
  [<-> >+>[-]<<-]
  <
  [
    not matching closing bracket
    >+>[<+<+>> >+<-]
    +++++[>--------<-]
    >
    [
      not open paren
      <<+>
      ++++[>-----<-]>
      [
        not open angle bracket
        <+++++[>------<-]>-
        [
          not open square bracket
          <++++[>--------<-]>
          [
            not open brace
            ,>
          ]
        ]
      ]
    ]
    <
  ]
  ,
]
<<[>]
>.

Espera entrada sin una nueva línea final. Imprime \x00para falso y \x01para verdadero.

Pruébalo en línea.

Enfoque: mantenga una pila comenzando \x01y presione el corchete de cierre correspondiente cada vez que se encuentre un corchete de apertura. Antes de verificar si el carácter actual es un paréntesis de apertura, primero verifique si es igual al paréntesis de cierre en la parte superior de la pila, y si es así, revíselo. Si no es el corchete de cierre adecuado ni el corchete de apertura, consuma el resto de la entrada mientras mueve el puntero hacia la derecha. Al final, verifique si el puntero está al lado de la inicial \x01.


2

Grime v0.1, 34 bytes

M=\(M\)|\[M\]|\{M\}|\<M\>|MM|_
e`M

Imprime 1para un partido y 0para ningún partido. Pruébalo en línea!

Explicación

Grime es mi lenguaje de coincidencia de patrones 2D diseñado para este desafío ; También se puede utilizar para unir cadenas 1D. Esta es mi primera respuesta con eso. Modifiqué Grime hoy, pero solo para cambiar el carácter de un elemento de sintaxis (en `lugar de ,), para que no afecte mi puntaje.

M=                         Define pattern called M that matches:
\(M\)|\[M\]|\{M\}|\<M\>      a smaller M inside matched brackets,
|MM                          or two smaller Ms concatenated,
|_                           or the empty pattern.
e`M                        Match the entire input against M.

2

Reng v.3.3, 137 bytes, sin competencia

Pruébalo aquí!

aií0#zl2,q!~1ø
:"]"eq!v:"}"eq!v:">"eq!v:")"eq!v)1z+#z
ve¤[2-2<       <       <     +1<
>]?v$$$zÀ0#z >ðq!vlqv¤l2%[1Ø
   \$2+)1z+#z/   ~n1/

Hay un poco más de golf por hacer, pero al menos funciona. Agregué un comando ðpara realizar un seguimiento de las pilas después de este desafío para que esto sea remotamente posible / fácil. Explicaré esto un poco, pero generalmente realiza un seguimiento de todas las cadenas iteradas y busca repeticiones; Si hay una repetición, entonces la cadena es irreducible. De lo contrario, la cadena se reducirá a la cadena / pila vacía y se generará 1. De lo contrario, no se producirá ninguna salida.


2

PowerShell v2 +, 63 62 bytes

param($a)for(;$a-ne$b){$a=($b=$a)-replace"\[\]|\(\)|<>|{}"}!$a

No se puede detectar JavaScript, pero actualmente está eliminando los otros que no son esolangs.

Enfoque similar como otras respuestas: un bucle simple que continúa tanto tiempo como podemos eliminar uno de [], ()o <>(con varios caracteres extraños, porque tenemos que escapar de los especiales de expresiones regulares). Usamos $bcomo ayudante en el camino para recordar cómo se estableció nuestro bucle anterior $a. Una variable no inicializada es $null, por lo tanto, la primera vez que se encuentra el bucle, $aobviamente no es igual a $null.

Al final del ciclo, $aestá vacío o no, y el Booleano-no de esa cadena es Trueo False.

Ejemplo

PS C:\Tools\Scripts\golfing> .\are-the-brackets-fully-matched.ps1 "[({})]"
True

PS C:\Tools\Scripts\golfing> .\are-the-brackets-fully-matched.ps1 "[({])}"
False

2

C, 121 122 114 bytes

¡Afeitado de 8 bytes gracias a @xsot!

a[99],i,k;main(c){for(;read(0,&c,!k);c%7&2?k|=a[i--]^c/9:(a[++i]=c/9))k|=!strchr("()[]{}<>",c);putchar(48+!k*!i);}

Utiliza una pila.


Me gusta el c%7&2. En realidad, no necesitas k. En su lugar, simplemente puede incrementar el lugar idonde lo modificaría, kya que de itodos modos debe verificar si es cero. Algo como esto (código no probado): a[99],i;main(c){for(;read(0,&c,1);c%7&2?i+=a[i--]^c/9:(a[++i]=c/9))i+=!strchr("()[]{}<>",c);putchar(48+!i);}.
xsot

@xsot - ¿Incrementando trabajaré? También debemos evitar suscribir la matriz con un valor negativo, por lo que debemos probar i o k en for.
mIllIbyte

Ah, ya veo. Sin embargo, todavía hay margen de mejora:a[99],i,k;main(c){for(;read(0,&c,!k);c%7&2?k|=a[i--]^c/9:(a[++i]=c/9))k|=!strchr("()[]{}<>",c);putchar(48+!i*!k);}
xsot

@xsot - ¡Gracias! Para resumir los ahorros, lea 5 bytes guardados, ^ guardado uno y el operando medio del operador condicional guardado 2. Me sorprende que el operando medio del operador condicional pueda ser una asignación. Pensé que habría un error, algo así como "falta: antes =".
mIllIbyte

@xsot - Intenté incrementar i en lugar de usar k, como sugirió por primera vez: a[99],i;main(c){for(;read(0,&c,1);c%7&2?i+=a[i]^c/9?1:-1:(a[++i]=c/9))i+=!strchr("()[]{}<>",c);putchar(48+!i);}Pero esto todavía no funciona para entradas como ())), ya que el "estallido" de la pila en realidad no pone a cero los valores en la matriz.
mIllIbyte

2

Java 7, 156 151 bytes

class A{public static void main(String[]a){for(int i=0;i<-1>>>1;++i,a[0]=a[0].replaceAll("<>|\\[]|\\(\\)|\\{}",""));System.out.print(a[0].isEmpty());}}

No espero que gane ningún premio, pero todavía no vi una respuesta de Java. Además, me gusta acechar alrededor de PPCG y me gustaría poder votar / comentar otras respuestas.

La entrada se proporciona como parámetros del programa. Esto sigue el mismo formato que muchas otras respuestas aquí, ya que forma un reemplazo de expresiones regulares en un bucle. Originalmente lo hice bucle N veces donde N es la longitud de la cadena original pero el bucle Integer.MAX_VALUEes más corto:]. Esto debería estar bien porque Integer.MAX_VALUEes la longitud máxima de a Stringen Java, por lo que hay una suposición implícita de que la longitud de entrada es algo que Java puede manejar. El tiempo de ejecución es bastante malo (tomó alrededor de 20 minutos en mi computadora portátil) a causa del bucle, pero no vi ninguna restricción al respecto.


2

Haskell , 151 bytes

infix 1#
'(':x#y=x#')':y
'<':x#y=x#'>':y
'[':x#y=x#']':y
'{':x#y=x#'}':y
')':x#')':y=x#y
'>':x#'>':y=x#y
']':x#']':y=x#y
'}':x#'}':y=x#y
""#""=1
_#_=0

Pruébalo en línea!


Algunas cosas: como la función (#)debe llamarse con la cadena vacía como segundo argumento, debe contar (#"")para el recuento de bytes. También solo Truey Falsese consideran verdadero / falso, consulte la Guía de reglas de golf .
Laikoni

1
Sin embargo, las cuatro líneas con los paréntesis de cierre se pueden reemplazar a:x#b:y|a==b=x#y, reduciendo los bytes a 113: ¡ Pruébelo en línea!
Laikoni

2

2

Python 2.7, 96 bytes

def r(s):i=max(map(s.find,['()','[]','{}','<>']));return not len(s)if i<0 else r(s[:i]+s[i+2:])

2
Bienvenido al sitio!
DJMcMayhem

1

Python 2, 80 bytes

def m(s,i=0):exec's=s.replace("[({<])}>"[i%4::4],"");i+=1;'*4*len(s);return"">=s

1

Julia, 51 bytes

~z=z==(n=replace(z,r"\(\)|\[]|{}|<>",""))?z=="":~n

La menos loca de varias opciones. Como era de esperar, aprovechar el poder de la expresión regular es el camino más corto para la coincidencia de cadenas, pero esto realmente solo se aplica si el patrón para coincidir es regular. Intentar hacer patrones recursivos PCRE termina aumentando el tamaño del código, ya sea al ver si la cadena completa es la coincidencia o al anclar los extremos y luego crear una construcción para especificar el cuerpo interno para la recursividad de expresiones regulares. Ninguno de los dos es bonito o propicio para el golf codificado.

Explicación:

~z=                            # Define ~z to be the following:
    z==(                       # If z is equal to                                     
        n=replace(z,           # z with the replacement of 
            r"\(\)|\[]|{}|<>", # adjacent matching brackets ((),[],{}, or <>)
            ""                 # with empty strings
        )                      # (which is assigned to n)
    )?z==""                    # whether z is an empty string
    :~n                        # else ~ applied to the substituted string

La función elimina repetidamente pares de paréntesis adyacentes de su único argumento, y devuelve verdadero si puede derivar una cadena vacía de esta manera.


1

sed, 39 36 bytes (34 para código, 2 para -r)

:a
s/\(\)|\[]|<>|\{}//;ta
/./c0
c1

Pruébalo en línea!

Versión sed de lo que parece ser el enfoque estándar. Requiere expresiones regulares extendidas ( sed -r)

Guardado 3 bytes gracias a Cows quack


Puede eliminar el aes :ay taguardar bytes
Kritixi Lithos

@ KritixiLithos Aparentemente fue un error en GNU sed que se eliminó en 4.3 . Probablemente dejaría caer esos personajes si esta entrada estuviera lo suficientemente cerca del líder para que tenga la oportunidad de ganar, pero como no lo es, lo dejaré en una forma más portátil para que no deje de funcionar. a medida que más sistemas se actualicen a 4.3.
Rayo

1
Mirando hacia atrás en esto, estoy seguro de que puede caer el qde /./y soltar las llaves allí también. Pruébalo en línea! Esto se debe a cómo cfunciona el
hange

@Cowsquack Gracias. Editado
Ray

0

05AB1E, 9 bytes

žu2ôõ:g2Q

La entrada se da entre comillas.

Pruébalo en línea!

Explicación:

žu          # Push "()<>[]{}"
  2ô        # Split into pieces of size 2
    õ       # Push empty string
            # Implicit input
      :     # Infinite replacement
       g2Q  # Is length equal to 2?
            # Implicit print

0

Clojure, 153 bytes

Más tiempo que incluso C y Brainfuck responden: o

(defn f[[s & r]](if s(let[[a b](split-at(.indexOf(reductions + 1(for[c r](get(zipmap[s({\(\)\[\]\{\}\<\>}s)][1 -1])c 0)))0)r)](and(not=()a)(f(butlast a))(f b))))1)

No usa expresiones regulares, en su lugar usa el primer carácter para determinar cuál es la etiqueta de cierre y encuentra el primer índice donde ese corchete está equilibrado (la suma acumulativa es cero). Luego verifica iterativamente que lo que está entre corchetes y después de los corchetes son válidos.

Tengo que ver si hay un mejor enfoque ...


0

Lua , 295 bytes

f = false g = string.gsub t=table s={}b=io.read()for c in b:gmatch('.')do if c:find("[%[<{%(]")then s[#s + 1] = g(g(g(g(c,"<",">"),"{","}"),"%[","]"),"%(",")")elseif c:find("[%]>}%)]")then if t.remove(s)~=c then print(f)return end else print(f)return end end if#s>0 then print(f)else print(1)end

Versión sin golf

f = false
g = string.gsub
t=table
s={} --Define a stack of opening brackets
b=io.read() --get the input
for c in b:gmatch('.') do   --for every character
    if c:find("[%[<{%(]") then
        s[#s + 1] = g(g(g(g(c,"<",">"),"{","}"),"%[","]"),"%(",")") --if the current character is an opening bracket, push the closing bracket onto the stack
    elseif c:find("[%]>}%)]") then
        if t.remove(s)~=c then
            print(f) --if the character is a closing bracket, pop the closing bracket off the stack and test if they match, if not print false
            return
        end
    else 
        print(f) --if the character is not a bracket print false
        return
    end
end
if #s>0 then
    print(f) --if there are still brackets on the stack print false
else
    print(1) --print 1 there are no brackets on the stack
end

Pruébalo en línea!



0

R, 298

function(.){s=strsplit;u=paste0;.=s(.,"")[[1]];p=s("><)(}{][","")[[1]];.[!.%in%p]="§";for(i in 1:4*2){.[.==p[i]]=sprintf("S('%s',{",p[i]);.[.==p[i-1]]=sprintf("},'%s');",p[i])};S=function(H,B,T)if(H!=T)stop();r=try(eval(parse(,,u(.,collapse=""))),1);if(inherits(r,"try-error"))FALSE else TRUE}

El enfoque aquí es convertir la secuencia en código R y luego intentar analizarla y evaluarla. Si eso da un error, entonces regrese FALSE.

Pero hay un pequeño problema ... reglas de R como soportes son diferentes, por lo que <y >no son soportes en absoluto, y los otros tipos tienen sus propias reglas. Esto se resuelve con un enfoque revolucionario: una función chirriante, cuya única función es señalar un error si su cabeza y cola chirrían de diferentes maneras.

Por ejemplo, []se transforma en S('[', {}, ']'), donde S se define como ...

S=function(H,B,T)if(H!=T)stop() 

Debido a que el chirrido de la cabeza y el de la cola coinciden, no se produce ningún error.

Algunos otros ejemplos (la parte izquierda es una secuencia de paréntesis y la parte derecha es su transformación en un código R válido que se puede evaluar):

[}     -->  S('[', {}, '}')     # squeaks an error
[()]   -->  S('[', {S('(',{},'(')}, "[")
({[]}) -->  S('(',{S('{',{S('[',{},'[');},'{');},'(');

Algunas otras secuencias de paréntesis darán lugar a errores de análisis:

[[)    -->   S('[',{S('[',{},'('); 

Entonces, la parte restante solo detecta los errores y devuelve FALSO si hay alguno, y VERDADERO si no hay ninguno.

El código humano-legible:

 sqk <- function(.){
   s=strsplit;u=paste0
   .=s(.,"")[[1]]            # break the argument up into 1-character pieces
   p=s("><)(}{][","")[[1]]   # vector of brackets
   .[!.%in%p]="§"            # replace anything besides brackets by § (--> error)
   for(i in 1:4*2){     
     .[.==p[i]]=sprintf("S('%s',{",p[i])    # '<' -->   S('<',{     ... etc
     .[.==p[i-1]]=sprintf("},'%s');",p[i])  # '>' -->   },'<');     ... etc  
   }
   S=function(H,B,T)if(H!=T)stop()          # define the working horse
   r=try(eval(parse(,,u(.,collapse=""))),1) # evaluate the sequence
   if(inherits(r,"try-error"))FALSE else TRUE   # any errors?
   }

Aplicandolo en casos de muestra:

truthy<-readLines(textConnection("()
[](){}<>
(((())))
({[<>]})
[{()<>()}[]]
[([]{})<{[()<()>]}()>{}]"))
falsy<-readLines(textConnection("(
}
(<2)>
(()()foobar)
[({}<>)>
(((()))"))
> sapply(truthy,sqk)
                      ()                 [](){}<>                 (((()))) 
                    TRUE                     TRUE                     TRUE 
                ({[<>]})             [{()<>()}[]] [([]{})<{[()<()>]}()>{}] 
                    TRUE                     TRUE                     TRUE 
> sapply(falsy,sqk)
           (            }        (<2)> (()()foobar)     [({}<>)>      (((())) 
       FALSE        FALSE        FALSE        FALSE        FALSE        FALSE 
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.