Os suportes são totalmente compatíveis?


56

Você deve escrever um programa ou função que use uma sequência de colchetes e produza se essa sequência é ou não totalmente correspondida. Seu programa deve imprimir um valor verdadeiro ou falso , e as E / S podem estar em qualquer formato razoável .

Regras e definições:

  • Para o propósito deste desafio, um "suporte" é qualquer um desses caracteres: ()[]{}<>.

  • Um par de colchetes é considerado "correspondente" se os colchetes de abertura e fechamento estiverem na ordem correta e não tiverem caracteres dentro deles, como

    ()
    []{}
    

    Ou se todos os subelementos dentro dele também corresponderem.

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

    Os subelementos também podem ser aninhados com várias camadas de profundidade.

    [(){<><>[()]}<>()]
    <[{((()))}]>
    
  • Uma cadeia é considerada "Totalmente compatível" se e somente se:

    1. Cada caractere é um colchete,

    2. Cada par de suportes possui o suporte correto de abertura e fechamento e na ordem correta, e

    3. Cada suporte é correspondido.

  • Você pode assumir que a entrada conterá apenas ASCII imprimível .

Teste de E / S

Aqui estão algumas entradas que devem retornar um valor verdadeiro:

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

E aqui estão algumas saídas que devem retornar um 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 costume, esse é um código de golfe, então as brechas padrão se aplicam e a resposta mais curta em bytes vence.



7
Nota para potenciais eleitores próximos: O desafio que vinculei também inclui uma ordem de prioridade para os tipos de colchetes, para que não possam ser aninhados em uma ordem arbitrária. Eu acho que faz com que seja suficientemente diferente.
Martin Ender

É [}uma partida? E se não, onde é excluído por essas regras?
precisa saber é o seguinte

2
@EJP Não, não é. Each pair of brackets has the correct opening and closing bracket and in the right order.
DJMcMayhem

6
Voto a favor da primeira solução entre parênteses
leo

Respostas:


17

05AB1E , 19 bytes

A entrada é dada entre aspas . Código:

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

Bem, porcaria, muitos bugs e recursos não implementados foram encontrados. Explicação:

"[](){}<>"           # 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 é realmente uma parte complicada. O que isso parece no pseudocódigo é:

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

Isso é coberto por esta parte do 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 você pode ver, isso é uma substituição infinita (feita até que a string não mude mais). Portanto, não preciso me preocupar em definir a substituição em um loop, pois isso já está embutido. Depois disso:

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

Usa a codificação CP-1252 . Experimente online! (ligeiramente modificado porque a versão acima está obsoleta).


11
Bem jogado!
SamyQc

11
Isso õfoi adicionado antes ?
Zacharý 10/09

@ Zacharý Sim, isso está correto #
Adnan

33

Flak cerebral , 1101, 1085 , 981 bytes

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

Experimente online!

Trata-se de 980 bytes de código-fonte e +1para o -asinalizador que permite entrada ASCII (mas saída decimal)

Esta é uma resposta que tenho vontade de escrever há muito, muito tempo. Pelo menos 6 meses. Eu esperei para postar isso porque sabia que responder a esse desafio seria muito difícil no cérebro. Mas vale a pena por uma razão muito importante: o código-fonte em si é uma entrada verdadeira, que é o ponto inteiro dessa própria linguagem.

E, como escrevi aqui , essa pergunta foi o que me inspirou a escrever ataques cerebrais.

Logo depois de escrever Os colchetes estão totalmente compatíveis ?, me fez pensar em quanta informação você pode armazenar apenas com colchetes correspondentes. Uma coisa que se destacou para mim foi que, embora você tenha apenas quatro "átomos" dos tipos:

(){}[]<>

você realmente tem 8 unidades de informação para transmitir, pois cada um desses tipos de colchetes pode estar vazio ou ter outros colchetes no meio, que são informações fundamentalmente diferentes. Então, decidi escrever uma linguagem que permitisse apenas colchetes correspondentes e onde colchetes vazios transmitissem algo diferente de colchetes com outros colchetes dentro deles.

Essa resposta levou aproximadamente duas horas para ser escrita. Admito que o jogo é muito ruim, principalmente porque muito do código é repetido para cada tipo de colchete. Mas estou bastante surpreso por ter conseguido escrever uma resposta, especialmente porque o Brain-Flak é um

Um esolang minimalista projetado para ser doloroso de usar

Vou tentar jogar no golfe mais tarde, mas queria divulgá-lo de qualquer maneira.

Eu tenho uma explicação detalhada, mas tem cerca de 6 mil caracteres, então acho que não seria sensato colar a coisa toda nessa resposta. Você pode ler aqui se quiser. Vou adicionar uma explicação mais curta aqui.

A idéia básica é repetir as seguintes etapas para cada caractere na pilha:

  • Verificamos cada caractere para ver se ele combina com qualquer colchete. Se for um colchete de abertura, colocamos um número na outra pilha de acordo com o seguinte mapeamento:

    ( = 1
    < = 2
    [ = 3
    { = 4
    
  • Em seguida, verificamos se ele corresponde a qualquer colchete de fechamento. Se isso acontecer, colocamos o número equivalente na pilha alternativa, assim como nos colchetes de abertura. Em seguida , verificamos se os dois primeiros números são iguais. Se estiverem, os dois serão acionados e o programa continuará normalmente. Caso contrário, limpamos as duas pilhas (para interromper o loop) e colocamos uma na pilha alternativa. Esta é essencialmente uma declaração de "interrupção".

  • Depois de verificar os 8 tipos de colchetes, pressionamos o valor dessa execução pelo loop. Como zeramos a maior parte, os únicos trechos que têm algum valor são os condicionais quando comparamos com colchetes. Portanto, se qualquer colchete for correspondido, o loop inteiro terá o valor 1. Se nenhum deles tiver, o loop inteiro terá o valor 0. Nesse caso, limparemos as duas pilhas e empurraremos 0 na pilha alternativa. Novamente, isso é como uma declaração de "interrupção".

Após a execução desse loop principal, o restante é bastante simples. Estamos na pilha principal (vazia) e a pilha alternativa está vazia (se os colchetes foram correspondidos) ou não está vazia se não estiver. Então, executamos isso:

#Toggle to the alternate stack
<>

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

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

Isso colocará 0 ou 1 na pilha principal e, quando o programa terminar, será impresso implicitamente.


  • Agradecemos ao @WheatWizard por apresentar um bom snippet "igual" e "lógico não" limpo de pilha, e por atualizar regularmente o wiki do github com exemplos úteis.

  • Obrigado a @ ASCII-only por escrever um metagolfer inteiro online que ajudou imensamente a escrever este programa


revisões

  • Removida alguma redundância push pop

  • Mudou minha lógica de contador zero


11
Awwwwwweeeeesommmmeeeee!
Arjun

23

Brain-Flak , 204 196 190 bytes

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

Experimente online!

-8 bytes graças ao Assistente de Trigo. -6 bytes graças a Jo King.

Explicação

Este programa armazena os códigos de caracteres de todos os colchetes não fechados atuais na segunda pilha. Os pares suporte <>, []e {}cada um tem códigos de caracteres que diferem por exatamente 2, por isso não há necessidade de verificá-los especificamente. O par ()difere apenas de 1; portanto, verificamos (especificamente e diminuímos efetivamente esse byte (na verdade, incrementamos todos os outros 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 não da diferença" (também conhecido como iguais) poderia ser mais curto([{}]<>({}))((){[()](<{}>)}{})
Assistente de trigo

Eu acho que você pode substituir o último cheque com ({<>[()]}())a -6 bytes
Jo rei

@JoKing Obrigado. Acho que nunca teria percebido isso.
Nitrodon

Sim, eu descobri isso na minha própria resposta e percebi que era aplicável à sua também
Jo King

13

JavaScript (ES6), 52 50 bytes

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

Remova repetidamente os colchetes até o resultado ser o mesmo do original e, em seguida, retorne false, a menos que a sequência esteja vazia.

Editar: salvou 2 bytes graças a @ edc65.



11

CJam, 25 24 23 21 bytes

Agradecimentos ao Sp3000 por salvar 2 bytes.
Obrigado a jimmy23013 por salvar 2 bytes.

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

Suíte de teste.

Trabalha essencialmente o mesmo que as outras respostas: que repetidamente remover (), [], <>e {}da corda e verificar se vamos acabar com a cadeia vazia. Para evitar ter que verificar quando terminamos, removemos os pares de Nvezes em que Né o comprimento da string, o que sempre é suficiente (já que cada iteração remove pelo menos dois caracteres, a menos que terminemos). Fico feliz em ver que isso não bate em Retina. :) (Embora Pyth ou Jelly possam ...)

Há um truque divertido de golfe aqui: para obter a sequência ()<>[]{}, usamos o seguinte:

{()<>}a`$

O, {()<>}é apenas um bloco (ou seja, uma função), que contém os outros colchetes como código. Com anós envolvemos o bloco em uma matriz. O `stringification que array, que dá "[{()<>}]". Finalmente, classificamos a string com $, que reorganiza os colchetes para ()<>[]{}.


Eu não estou familiarizado com o seu idioma, mas sua descrição do seu truque de golfe faz parecer ()<>[]{}`que funcionaria tão bem e teria o mesmo número de bytes, certo?
Mooing Duck

11
@MooingDuck Não, porque ()<>existem quatro operadores (decremento, incremento e, em seguida, comparação ou truncamento, dependendo dos operandos), que seriam executados imediatamente, enquanto {}denota um bloco (o equivalente a uma função do CJam), ou seja, um pedaço de código que é apenas pressionado na pilha sem avaliá-la imediatamente. É por isso que eu preciso {}agrupar o ()e <>, mas usar apara colocar tudo em uma matriz é menor que [...].
Martin Ender

10

Python, 67 bytes

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

Gera e avalia uma expressão que se parece com

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

e verifica se o resultado está vazio.

O Sp3000 salvou 8 bytes apontando que [],(),{}pode ser substituído sem aspas porque são objetos Python e que dois parênteses eram desnecessários.


8

Yacc, 119 bytes

Não usa regex / substituir.

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

Ungolfed

%%                              # 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(){}

Compilação

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

Uso

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

7

Pitão, 31 25 24 bytes

Jogou até 25 bytes graças ao FryAmTheEggMan Removido 1 byte

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

Experimente aqui: suíte de testes !

Eu ainda sou um novato Pyth, qualquer ajuda é apreciada.

Explicação

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

BTW, parabéns à outra resposta Pyth (que atualmente é 20 bytes)


Bem-vindo à Programação de Puzzles e Code Golf!
Adnan

@Adnan Obrigado! Este é o meu primeiro golfe!
FliiFe

Bom primeiro golfe! Com algum rearranjo e outras coisas, você pode chegar a 25: Vz=:z"<>|\[]|{}|\(\)"k;!z. Particularmente, você basicamente nunca precisará usar lse realmente não precisa do número e =adivinha automaticamente a primeira variável usada em uma expressão. Deixe-me saber se você gostaria de me explicar qualquer outra coisa no chat Pyth :)
FryAmTheEggman

@FryAmTheEggman Thanks! Eu não sabia que lera desnecessário, é bom saber. No começo, declarei uma função porque minha lógica era diferente e esqueci de removê-la. Devo incluir sua resposta à minha? (Eu sou um novato>. <)
FliiFe

3
Geralmente, se ele é publicado em um comentário, o autor do comentário deseja que você o use. Então vá em frente! :)
FryAmTheEggman

6

Pitão, 20 bytes

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

Experimente online: Conjunto de Testes

Repetidamente remove ocorrências de [], (), <>e {}por meio de separação e a re-fusão. Verifica se a sequência resultante está vazia ou não.


4

Javascript ES6, 54 bytes

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

Usa uma implementação de substituição recursiva. Simples o suficiente.



4

Perl, 34 33 bytes

Inclui +2 para -lp

Execute com entrada no STDIN:

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

brackets.pl:

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

Localiza o primeiro par de colchetes sem nada entre eles e o remove enquanto houver. Em seguida, verifica se a sequência final está vazia.


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

Seria ótimo se você pudesse fornecer uma explicação também.
Prashant Pokhriyal

@ Dadá Claro. Eu devo estar ficando senil ..
Ton Hospel

4

Flak cerebral , 204 bytes

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

Experimente online!

Não é tão curto quanto a resposta de Nitroden , mas usa uma abordagem muito diferente. Este percorre a entrada repetidamente, removendo pares de colchetes correspondentes a cada vez até que não sobrem mais. Nesse ponto, se houver algo sobrando na pilha, a sequência não foi totalmente correspondida.

Explicação:

(())  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

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

Formatado:

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

Espera entrada sem uma nova linha à direita. Imprime \x00para falso e \x01verdadeiro.

Experimente online.

Abordagem: mantenha uma pilha começando com \x01e empurre o suporte de fechamento correspondente sempre que um suporte de abertura for encontrado. Antes de verificar se o caractere atual é um colchete de abertura, verifique primeiro se é igual ao colchete de fechamento na parte superior da pilha e, se for o caso, solte-o. Se não for o suporte de fechamento adequado nem o suporte de abertura, consuma o restante da entrada enquanto move o ponteiro para a direita. No final, verifique se o ponteiro está ao lado da inicial \x01.


2

Grime v0.1, 34 bytes

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

Imprime 1para uma correspondência e 0sem correspondência. Experimente online!

Explicação

Grime é minha linguagem de correspondência de padrões 2D projetada para esse desafio ; também pode ser usado para corresponder a cadeias 1D. Esta é a minha primeira resposta com isso. Modifiquei o Grime hoje, mas apenas para alterar o caractere de um elemento da sintaxe (em `vez de ,), para que não afete minha pontuação.

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, não-competidor

Experimente aqui!

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/

Há um pouco mais de golfe a ser feito, mas pelo menos funciona. Eu adicionei um comando ðpara acompanhar as pilhas após esse desafio para que isso seja possível / facilmente remotamente. Vou explicar isso daqui a pouco, mas geralmente acompanha todas as strings repetidas e procura repetições; se houver uma repetição, a sequência será irredutível. Caso contrário, a cadeia será reduzida para a cadeia / pilha vazia e será gerada 1. Caso contrário, nenhuma saída será produzida.


2

PowerShell v2 +, 63 62 bytes

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

Não é possível capturar o JavaScript, mas atualmente está superando os outros não-esolangs.

Abordagem semelhante como outras respostas: um loop simples que continua contanto que pode remover um dos [], ()ou <>(com vários caracteres estranhos porque precisamos escapar os especiais regex). Usamos $bcomo auxiliar ao longo do caminho para lembrar como nosso loop anterior $afoi definido. Uma variável não inicializada é$null , portanto, a primeira vez que o loop é encontrado, $aobviamente não é igual a $null.

No final do loop, $a está vazio ou não, e o Boolean-not dessa sequência é Trueou False.

Exemplo

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

Raspada de 8 bytes graças 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);}

Usa uma pilha.


Eu gosto do c%7&2. Na verdade, você não precisa k. Em vez disso, você pode simplesmente incrementar ionde você modificaria, kpois você precisa verificar se, ieventualmente, é zero. Algo como isto (código não testado): 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 - O incremento de trabalho? Também precisamos evitar a assinatura do array com um valor negativo, portanto, precisamos testar i ou k no for.
MIllIbyte

Ah entendo. Ainda há espaço para melhorias: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 06/04

@xsot - Obrigado! Para resumir a economia, leia 5 bytes salvos, ^ salvou um e o operando do meio do operador condicional salvou 2. Surpreende-me que o operando do meio do operador condicional possa ser uma atribuição. Eu pensei que haveria um erro, algo como "falta: antes =".
MIllIbyte 6/04

@xsot - Tentei incrementar i em vez de usar k, como você sugeriu pela primeira 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);}Mas isso ainda não funciona para entradas como ())), pois "popping" da pilha não zera os valores na matriz.
MIllIbyte 6/04

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());}}

Não estou esperando que isso ganhe nenhum prêmio, mas ainda não vi uma resposta em Java. Além disso, gosto de espreitar o PPCG e gostaria de poder votar / comentar outras respostas.

A entrada é fornecida como parâmetros do programa. Isso segue o mesmo formato de muitas outras respostas aqui, na medida em que pré-forma uma substituição de regex em um loop. Originalmente, eu tinha o loop N vezes em que N é o comprimento da string original, mas o loop Integer.MAX_VALUEé menor:]. Isso deve estar ok, porque Integer.MAX_VALUEé o comprimento máximo de um Stringem Java, portanto há uma suposição implícita de que o comprimento da entrada é algo que pode ser manipulado pelo Java. O tempo de execução é muito ruim (levou cerca de 20 minutos no meu lappytop) por conta do loop, mas não vi nenhuma restrição sobre isso.


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

Experimente online!


Algumas coisas: como a função (#)precisa ser chamada com a string vazia como segundo argumento, você precisa contar (#"")para a contagem de bytes. Também apenas Truee Falsesão consideradas verdadeiras / falsas, consulte o Guia de Regras de Golfe .
Laikoni

11
No entanto, as quatro linhas com parênteses de fechamento podem ser substituídas a:x#b:y|a==b=x#y, reduzindo os bytes para 113: Experimente online!
Laikoni


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
Bem vindo ao site!
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

O menos insano de várias opções. Sem surpresa, aproveitar o poder do regex é o caminho mais curto para a correspondência de cadeias, mas isso realmente só se aplica se o padrão a corresponder for regular. Tentar fazer padrões recursivos PCRE acaba aumentando o tamanho do código, verificando se a sequência inteira é a correspondência ou ancorando as extremidades e criando uma construção para especificar o corpo interno da recursão de regex. Nenhum dos quais é bonito ou propício para codificar golfe.

Explicação:

~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

A função remove repetidamente pares adjacentes de parênteses de seu único argumento e retorna true se puder derivar uma string vazia dessa maneira.


1

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

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

Experimente online!

versão sed do que parece ser a abordagem padrão. Requer expressões regulares estendidas (sed -r )

Economizou 3 bytes graças ao vacas charlatão


Você pode remover o aé :ae tapara salvar bytes
Kritixi Lithos

@KritixiLithos Aparentemente, foi um erro no GNU sed que foi removido no 4.3 . Provavelmente, eu soltaria esses caracteres se essa entrada estivesse próxima o suficiente do líder para ter uma chance de ganhar, mas como não é, vou deixá-la na forma mais portátil para que não pare de funcionar. à medida que mais sistemas atualizam para 4.3.
Ray

11
Olhando para trás, isso, eu tenho certeza que você pode soltar a qpartir /./e deixar cair as chaves lá também. Experimente online! Isto é por causa de como change funciona
Kritixi Lithos

@Cowsquack Thanks. Editado.
Ray

0

05AB1E, 9 bytes

žu2ôõ:g2Q

A entrada é dada entre aspas.

Experimente online!

Explicação:

ž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

Respostas mais longas que C e Brainfuck:

(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)

Não usa regex, em vez disso, usa o primeiro caractere para determinar qual é a marca de fechamento e localiza o primeiro índice em que esse colchete está balanceado (a soma acumulada é zero). Em seguida, verifica iterativamente se o que está entre colchetes e depois entre colchetes é válido.

Tenho que ver se existe uma abordagem melhor ...


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

Versão Ungolfed

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

Experimente online!



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}

A abordagem aqui é converter a sequência em código R e, em seguida, tente analisá-la e avaliá-la. Se isso der um erro, retorne FALSE.

Mas há um pequeno problema ... As regras de R para colchetes são diferentes, então < e >não são suportes em tudo, e os outros tipos têm regras próprias. Isso é resolvido por uma abordagem revolucionária - uma função de chiado, cuja única função é sinalizar um erro se a cabeça e a cauda chiarem de maneiras diferentes.

Por exemplo, []é transformado em S('[', {}, ']'), onde S é definido como ...

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

Como o chiado da cabeça e o chiado da cauda correspondem, nenhum erro é gerado.

Alguns outros exemplos (a parte esquerda é uma sequência de colchetes e a parte direita é sua transformação em código R válido que pode ser avaliado):

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

Algumas outras seqüências de colchetes resultarão em erros de análise:

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

Portanto, a parte restante apenas captura os erros e retorna FALSE, se houver, e TRUE, se não houver.

O código legível por humanos:

 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?
   }

Aplicando-o em casos de amostra:

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 
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.