Teste se uma string está entre parênteses

15

Chamamos um grupo de parênteses de parêntesis abertos (, parênteses próximos correspondentes )e tudo dentro deles.

Um grupo ou sequência de parênteses é chamado de parênteses balanceado se não contiver nada ou apenas dois grupos parênteses balanceados entre parênteses.

Por exemplo:

The string   "(()())()"      is parenthesly balanced
              (    )()       Because it contains exactly 2 parenthesly balanced parens groups
               ()()          The left one is parenthesly balanced because it contains 2 parenthesly balanced parens groups (balanced because they are empty). The right one is parenthesly balanced because it contains nothing.

Da mesma forma:

The string   "(()(()))()"    is not parenthesly balanced
              (      )()     Because it contains a parens group that is not parenthesly balanced: the left one
               ()(  )        The left one is not balanced because it contains a parens group that is not balanced: the right one
                  ()         The right one is not balanced because it only contains one balanced group.

Portanto, uma string ou grupo parensly equilibrado entre parênteses deve:

  • Não contém nada.
  • Ou conter apenas e exatamente 2 grupos parênteses equilibrados entre parênteses. Não deve conter mais nada.

Tarefa:

Sua tarefa é escrever uma função ou programa que verifique se uma determinada sequência é equilibrada entre parênteses ou não.

Entrada:

A entrada será uma sequência ou lista de caracteres ou algo semelhante. Você pode assumir que a sequência consistirá apenas dos caracteres '('e ')'. Você também pode assumir que cada um parêntese aberto (terá seus paren perto de correspondência ), então não se preocupe com cordas, como "((("ou ")("ou "(())("...

Nota: Como mencionado por @DigitalTrauma em seu comentário abaixo, ele está ok para subtitute a ()combinação por outros caracteres (como <>, []...), se é fazendo com que o trabalho adicional como escapar em algumas línguas

Resultado:

Qualquer coisa para sinalizar se a sequência está entre parênteses ou não (verdadeira ou falsa, 1 ou 0, ...). Inclua na sua resposta o que sua função / programa deverá gerar.

Exemplos:

""                                        => True
"()()"                                    => True
"()(()())"                                => True
"(()(()(()())))(()())"                    => True
"(((((((()())())())())())())())()"        => True
"()"                                      => False
"()()()"                                  => False
"(())()"                                  => False
"()(()(())())"                            => False
"(()())(((((()())()))())())"              => False
"()(()()()())"                            => False
"()(()(()())()())"                        => False

Os dois últimos exemplos realmente fizeram a diferença!

Boa sorte!

ibrahim mahrir
fonte
Qualquer coisa para sinalizar se a string está entre parênteses ou não. É necessária uma saída consistente, ou seja, apenas dois valores?
Luis Mendo
@LuisMendo Podem ser categorias. ou seja, valores verdadeiros para sinalizar a veracidade e valores falsos para sinalizar o contrário. Portanto, pode haver mais, mas deve ser consistente, no entanto.
ibrahim mahrir
1
Tudo bem se eu pegar uma lista binária como entrada? Por exemplo, "(()())()"seria representado como [0, 0, 1, 0, 1, 1, 0, 1]. Isso eliminaria a necessidade de converter a entrada em código de caractere e subtrair.
JungHwan Min 01/08/2018
Pergunta relacionada: codegolf.stackexchange.com/questions/166457/…
Windmill Cookies
1
@WindmillCookies Não vejo como isso está relacionado a este. Coisas totalmente diferentes. Até o conceito é diferente.
ibrahim mahrir

Respostas:

8

Japonês v2, 20 bytes

V="()"V¥iU1 eViV²1 V

Teste online!

Todo mundo entendeu mal o desafio em primeiro lugar e, apesar de que cada par de parênteses teve que conter um mesmo número de sub-pares, quando na verdade o desafio realmente pede a 0 ou 2 sub-pares. Então, aqui está minha resposta revisada, usando a mesma técnica de antes.

Ainda podemos resolver o desafio com substituição recursiva. O problema é que, em vez de apenas remover todas as ocorrências de ()(), precisamos garantir que não haja mais nada no mesmo invólucro além do ()()(em outras palavras, não ()()()()ou nada disso). Podemos fazer isso substituindo recursivamente (()())por ().

O novo problema é que a entrada em si não possui um par de parênteses externos (pois isso a tornaria uma string não equilibrada entre parênteses), forçando-nos a envolvê-la em um par extra para reduzi-la completamente. Finalmente, o resultado final para seqüências de caracteres balanceadas é agora, em ()vez da sequência vazia, portanto, verificamos a igualdade em vez de apenas tirar o NOT lógico da saída.

ETHproductions
fonte
7

sed 4.2.2, 30

:
s/(()())/()/
t
/^()()$\|^$/q1

Experimente online .

Isso retorna um código de saída do shell 1 para True e 0 para False.

:               # label
s/(()())/()/    # replace "(()())" with "()"
t               # jump back to label if above replacement matched
/^()()$\|^$/q1  # exit code 1 if remaining buffer is exactly "()()" or empty
                # otherwise exit with code 0
Trauma Digital
fonte
7

Perl 5 -lp, 24 22 bytes

$_=/^((<(?1)?>){2})?$/

Experimente online! O link inclui casos de teste. Editar: salvou 2 bytes graças a @JoKing. Explicação: Apenas uma regex recursiva. O grupo de captura externa representa uma sequência balanceada como uma <seguida por uma sequência balanceada opcional seguida por uma >, duas vezes. Observe que a maioria das outras respostas é capaz de usar ()s, mas isso custa dois bytes extras:

$_=/^((\((?1)?\)){2})?$/

Experimente online! O link inclui casos de teste.

Neil
fonte
3
Como você pode usar outros pares de colchetes, você pode salvar dois bytes usando<>
Jo King
1
@JoKing Quase todas as outras respostas foram capazes de usar ()s, então não achei que fosse uma comparação justa, no entanto, vejo que a resposta da APN da @ ngn também usa <>s, então atualizei esta.
Neil
6

Rotina de código de máquina 6502 , 48 bytes

A0 00 84 FD A2 00 B1 FB F0 0E C8 C9 29 18 F0 06 8A 48 E6 FD 90 EE B0 0A E0 01
90 06 E0 02 38 D0 01 18 A5 FD F0 09 C6 FD 68 AA E8 B0 F5 90 D7 60

Espera um ponteiro para uma string em $fb/ $fcque deve conter apenas (e ). Limpa o sinalizador C (Carry) se a string for "paranthesely equilibrada", define-a de outra forma (que é um idioma típico no 6502, defina carry "on error"). Não faz nada sensato na entrada inválida.

Embora o algoritmo seja recursivo, ele não se chama (o que exigiria mais bytes e tornaria a posição do código dependente), mas, em vez disso, mantém uma profundidade de recursão e usa ramificação "simples".

Desmontagem comentada

; function to determine a string is "paranthesly balanced"
;
; input:
;   $fb/$fc: address of the string
; output:
;   C flag set if not balanced
; clobbers:
;   $fd:     recursion depth
;   A,X,Y

 .isparbal:
A0 00       LDY #$00            ; string index
84 FD       STY $FD             ; and recursion depth
 .isparbal_r:
A2 00       LDX #$00            ; set counter for parantheses pairs
 .next:
B1 FB       LDA ($FB),Y         ; load next character
F0 0E       BEQ .done           ; end of string -> to final checks
C8          INY                 ; increment string index
C9 29       CMP #$29            ; compare with ')'
18          CLC                 ; and reset carry
F0 06       BEQ .cont           ; if ')' do checks and unwind stack
8A          TXA                 ; save counter ...
48          PHA                 ; ... on stack
E6 FD       INC $FD             ; increment recursion depth
90 EE       BCC .isparbal_r     ; and recurse
 .cont:
B0 0A       BCS .unwind         ; on previous error, unwind directly
 .done:
E0 01       CPX #$01            ; less than one parantheses pair
90 06       BCC .unwind         ; -> ok and unwind
E0 02       CPX #$02            ; test for 2 parantheses pairs
38          SEC                 ; set error flag
D0 01       BNE .unwind         ; if not 2 -> is error and unwind
18          CLC                 ; clear error flag
 .unwind:
A5 FD       LDA $FD             ; check recursion depth
F0 09       BEQ .exit           ; 0 -> we're done
C6 FD       DEC $FD             ; otherwise decrement
68          PLA                 ; get "pair counter" ...
AA          TAX                 ; ... from stack
E8          INX                 ; and increment
B0 F5       BCS .unwind         ; continue unwinding on error
90 D7       BCC .next           ; otherwise continue reading string
 .exit:
60          RTS

Exemplo de programa assembler C64 usando a rotina:

Demonstração online

captura de tela

Código na sintaxe ca65 :

.import isparbal   ; link with routine above

.segment "BHDR" ; BASIC header
                .word   $0801           ; load address
                .word   $080b           ; pointer next BASIC line
                .word   2018            ; line number
                .byte   $9e             ; BASIC token "SYS"
                .byte   "2061",$0,$0,$0 ; 2061 ($080d) and terminating 0 bytes

.bss
linebuf:        .res    256

.data
prompt:         .byte   "> ", $0
truestr:        .byte   "true", $0
falsestr:       .byte   "false", $0

.code
inputloop:
                lda     #<prompt        ; display prompt
                ldy     #>prompt
                jsr     $ab1e

                lda     #<linebuf       ; read string into buffer
                ldy     #>linebuf
                ldx     #0              ; effectively 256
                jsr     readline

                lda     #<linebuf       ; address of string to $fb/fc
                sta     $fb
                lda     #>linebuf
                sta     $fc
                jsr     isparbal        ; call function

                bcs     isfalse
                lda     #<truestr
                ldy     #>truestr
                bne     printresult
isfalse:        lda     #<falsestr
                ldy     #>falsestr
printresult:    jmp     $ab1e           ; output true/false and exit

; read a line of input from keyboard, terminate it with 0
; expects pointer to input buffer in A/Y, buffer length in X
.proc readline
                dex
                stx     $fb
                sta     $fc
                sty     $fd
                ldy     #$0
                sty     $cc             ; enable cursor blinking
                sty     $fe             ; temporary for loop variable
getkey:         jsr     $f142           ; get character from keyboard
                beq     getkey
                sta     $2              ; save to temporary
                and     #$7f
                cmp     #$20            ; check for control character
                bcs     checkout        ; no -> check buffer size
                cmp     #$d             ; was it enter/return?
                beq     prepout         ; -> normal flow
                cmp     #$14            ; was it backspace/delete?
                bne     getkey          ; if not, get next char
                lda     $fe             ; check current index
                beq     getkey          ; zero -> backspace not possible
                bne     prepout         ; skip checking buffer size for bs
checkout:       lda     $fe             ; buffer index
                cmp     $fb             ; check against buffer size
                beq     getkey          ; if it would overflow, loop again
prepout:        sei                     ; no interrupts
                ldy     $d3             ; get current screen column
                lda     ($d1),y         ; and clear 
                and     #$7f            ;   cursor in
                sta     ($d1),y         ;   current row
output:         lda     $2              ; load character
                jsr     $e716           ;   and output
                ldx     $cf             ; check cursor phase
                beq     store           ; invisible -> to store
                ldy     $d3             ; get current screen column
                lda     ($d1),y         ; and show
                ora     #$80            ;   cursor in
                sta     ($d1),y         ;   current row
                lda     $2              ; load character
store:          cli                     ; enable interrupts
                cmp     #$14            ; was it backspace/delete?
                beq     backspace       ; to backspace handling code
                cmp     #$d             ; was it enter/return?
                beq     done            ; then we're done.
                ldy     $fe             ; load buffer index
                sta     ($fc),y         ; store character in buffer
                iny                     ; advance buffer index
                sty     $fe
                bne     getkey          ; not zero -> ok
done:           lda     #$0             ; terminate string in buffer with zero
                ldy     $fe             ; get buffer index
                sta     ($fc),y         ; store terminator in buffer
                sei                     ; no interrupts
                ldy     $d3             ; get current screen column
                lda     ($d1),y         ; and clear 
                and     #$7f            ;   cursor in
                sta     ($d1),y         ;   current row
                inc     $cc             ; disable cursor blinking
                cli                     ; enable interrupts
                rts                     ; return
backspace:      dec     $fe             ; decrement buffer index
                bcs     getkey          ; and get next key
.endproc
Felix Palmen
fonte
5

V , 21 , 20 bytes

é(Á)òÓ(“()()…)òø^()$

Experimente online! ou Verifique todos os casos de teste!

é(                      " Insert '(' at the beginning of the line
  Á)                    " Append ')' at the end
    ò         ò         " Recursively...
     Ó                  "   Remove...
      (                 "     '('
       “    …           "     (Limit the part that is removed to this section of the match)
        ()()            "     '()()'
             )          "     ')'
                        " (effectively, this replaces '(()())' with '()', but it's one byte shorter than the straightforward approach
               ø        " Count...
                ^()$    "   Lines containing exactly '()' and nothing more

Hexdump:

00000000: e928 c129 f2d3 2893 2829 2829 8529 f2f8  .(.)..(.()().)..
00000010: 5e28 2924                                ^()$
DJMcMayhem
fonte
Você pode explicar seu código para que eu possa (espero) encontrar uma caixa de teste que não funcione, como fiz com a resposta de @ Adàm .
ibrahim mahrir
@ibrahimmahrir Concluído.
DJMcMayhem
5

Braquilog , 28 bytes

Ẹ|~c["(",A,")(",B,")"]∧A;B↰ᵐ

Experimente online!

Explicação

                                    --  The string perfectly balanced iff
Ẹ                                   --      the string is empty
 |                                  --  or
  ~c["(",A,")(",B,")"]              --      the string can be written id the format of "($A)($B)"
                      ∧             --          where
                       A;B ᵐ        --          both A and B
                          ↰         --          are perfectly balanced
Kroppeb
fonte
4

C (gcc) , 113 bytes

p(a,r,e,n)char*a;{if(*a-40)return 1;for(r=1,e=0;e<2;r&=e++||*a==40)for(r*=n=p(++a);n+=*a++-40?~0:1;);r=r&&*a-40;}

Experimente online!

Explicação

p(a,r,e,n)char*a;{   // function and variable declaration
 if(*a-40)return 1;  // string does not start with '(', thus is empty
 for(r=1,e=0;e<2;    // r: return value, e: group id (look for exactly two groups)
 r&=e++||*a==40)     // after the first group, a second shall follow
  for(r*=n=p(++a);   // check that the group is itself balanced
  n+=*a++-40?~0:1;); // skip group
 r=r&&*a-40;}        // additionally, after those two groups there shall follow none

Experimente online!

Jonathan Frech
fonte
3

MATL , 26 25 bytes

oo~`tnw52B5LZttnb<]XB10X-

Experimente online!

Obrigado à resposta do @ETHProductions 'para a idéia "substituir (() ()) por ()"), e a pergunta de @JungHwan Min comenta a idéia de ver os colchetes como dígitos binários.

A saída é uma matriz vazia para a verdade, um número positivo para a falsey - que eu acho que é permitido pelo comentário do OP: "Podem ser categorias. Caso contrário, podemos adicionar, nno final, +1 byte, para ter 0 como saída de verdade e 1 como saída de falsey.

Com comentários:

o         % Convert the parantheses to their ASCII codes
          %  40 for '(', 41 for ')'
o         % Parity - 1 for odd, 0 for even
~         % Not - change 0 to 1 and vice versa, so '(' is now 1 and ')' 0
          % Input char array is now a binary array B
`         % Do-while loop
  tn          % Get the length of the array 
  w           % Bring the array B back on top
  52B         % Push the binary value of 52 on stack
              %  [1 1 0 1 0 0] (equivalent to '(()())')
  5L          % Push the constant [1 0] for '()'
  Zt          % Replace the sequence [1 1 0 1 0 0] in array B
              %  with [1 0]
  tn          % Get the length of the array after replacement 
  b<          % Has it decreased? If so, continue loop
  ]       % end loop
          % Final value for balanced input will be
          %  either [1 0 1 0] for the remaining outer '()()'
          %  or an empty array [] for empty '' input
XB        % Convert the final binary array back to decimal
10X-      % Set difference, remove 10 from that result 
          % Result is [] empty array for balanced input, otherwise 
          %  some decimal number ≠ 10 for unbalanced input
sundar - Restabelecer Monica
fonte
3

Haskell , 82 59 bytes

all(`elem`[0,2]).foldl(#)[0]
b#'('=0:b
(x:y:z)#_=y+1:z++[x]

Experimente online!

Suponho que ele possa ser jogado muito mais longe, já que é minha primeira vez jogando golfe em haskell, portanto, quaisquer truques ou comentários são bem-vindos.

EDIT - Obrigado @nimi por salvar 23 bytes (mais de 28% da submissão original :)

Vincent
fonte
1
Algumas dicas: não há necessidade de se ()locomovery+1 . Como funções anônimas são permitidos, você pode soltar a f=, r[0]é uma função adequada. Coloque a base r b[]no final e mude para uma função infix (por exemplo #), para poder usá-la b#_=. Você também pode alterar um pouco seu algoritmo criando a lista para verificar se 0es e 2passo a passo, em vez de carregá-lo pelas chamadas de rum acumulador r(x:y:z) ... = x : r (...) acom base r b [] = b. Faça a verificação após a chamada inicial r[0]. Ao todo, 73 bytes.
nimi
1
... ou melhor ainda: fique com o acumulador e mude para foldl(59 bytes): Experimente online! .
nimi
@nimi Muito obrigado, exatamente o tipo de dicas que eu estava procurando :)
Vincent
3

JavaScript (ES6), 63 bytes

Recebe a entrada como uma matriz de caracteres. Retorna false para parênteses balanceado, true para não parênteses equilibrado.

a=>[...a,k=0].some(c=>c<')'?!(a[k]=-~a[k++]):a[k]=~5>>a[k--]&1)

Experimente online!

Comentado

a =>                     // a[] = input array of characters; we are going to reuse it to
  [                      // store the number of parenthesis groups at each depth
    ...a,                // append all characters
    k = 0                // initialize k = current depth to 0 and append a value that will
  ]                      // be treated as a final closing parenthesis for the root level
  .some(c =>             // for each character c in this array:
    c < ')' ?            //   if c is an opening parenthesis:
      !(                 //     increment the number of groups at the current depth
        a[k] = -~a[k++]  //     increment the depth
      )                  //     yield false
    :                    //   else:
      a[k] = ~5          //     make sure that the current depth contains either 0 or 2
             >> a[k--]   //     groups, by shifting the 1-complement of 5 (101 in binary)
             & 1         //     and testing the least significant bit
                         //     it resets the number of groups to 0 if the bit is not set
                         //     otherwise, it forces some() to return true
                         //     decrement the depth
  )                      // end of some()

Recursivo, 54 bytes

Usando substituições recursivas (como em resposta Japt da ETHproductions ) é, no entanto, significativamente menor.

Recebe a entrada como uma sequência. Retorna 1 para equilibrado entre parênteses, 0 para não equilibrado entre parênteses.

f=s=>s==(s=s.split`(()())`.join`()`)?!s|s=='()()':f(s)

Experimente online!


Recursivo, 46 ​​bytes

Este gera um erro de recursão para não estar entre parênteses:

f=s=>!s|s=='()()'||f(s.split`(()())`.join`()`)

Experimente online!

Arnauld
fonte
Eu não sou tão bom em JavaScript, mas x [k] = - ~ x [k ++] pode ser substituído por x [k] ++; k ++ ou mesmo ++ x [k ++]?
Андрей Ломакин
2
@ АндрейЛомакин Não, porque x[k]é inicialmente indefinido e x[k]++daria NaN, ao passo que -~undefined1.
Arnauld
@ АндрейЛомакин Agora estou reutilizando a matriz de entrada, então a[k]inicialmente contém um caractere. Mas a mesma lógica se aplica às seqüências de caracteres: aplicar o ++operador sobre elas produz NaN, mas operadores bit a bit (como ~) forçam a serem coagidos 0previamente.
Arnauld
Leva o javascript a um nível totalmente novo. : D
ibrahim mahrir
3

Perl 6 ,  43 41  37 bytes

{my rule f{\([<&f>**2]?\)};?/^<&f>**2$|^$/}

Teste-o

{(my$f)=/\([<$f>**2]?\)/;?/^[<$f>**2]?$/}

Teste-o

{$!=/\([<$!>**2]?\)/;?/^[<$!>**2]?$/}

Teste-o

Expandido:

{  # bare block lambda with implicit parameter $_

  $! = # store regex into $! (no need to declare it)
  /
    \(

      [
        <$!> ** 2 # recurse into regex twice
      ]?          # optionally

    \)
  /;


  ?      # boolify (causes it to be run against $_)

    /
      ^         # beginning of string

      <$!> ** 2 # match using regex twice

      $         # end of string

    |           # or

      ^ $       # empty string
    /
}
Brad Gilbert b2gills
fonte
3

R , 71 bytes

f=function(s,r=sub('(()())','()',s,f=T))'if'(r==s,s==''|s=='()()',f(r))

Experimente online!

  • portabilidade da solução Japt recursiva de @ETHproductions
  • -2 bytes graças a @JayCe

Outra solução - mais longa - mas interessante para a abordagem diferente

R , 85 bytes

g=gsub;!sum(eval(parse(t=g('\\)\\(',')-(',g('\\)','-1)',g('\\(','(2+',scan(,'')))))))

Experimente online!

Explicação:

Pegue a sequência de entrada e substitua:

'('  with '(2+'
')'  with '-1)'
')(' with ')-('

depois avalia a expressão resultante. Se é igual a zero, é equilibrado, caso contrário, não é. O uso de sumé necessário apenas para manipular o caso de cadeia vazia, porque sua avaliação retorna NULL.

por exemplo

()(()()) => (2+-1)-(2+(2+-1)-(2+-1)-1) = 0
(()())   => (2+(2+-1)-(2+-1)-1)        = 1
digEmAll
fonte
Salve dois bytes:f=function(s,r=sub('(()())','()',s,f=T))'if'(r==s,s==''|s=='()()',f(r))
JayCe 8/08/19
Você deve colocar a solução mais curta primeiro
ASCII única
@ ASCII-only: você está certo, mas já que é basicamente uma portabilidade de outra solução parecia que "roubar": P
digEmAll
3
@digEmAll Bem, em uma série de desafios aqui a maioria dos desafios fazer apenas porta de uma outra solução
ASCII-only
2

05AB1E , 18 16 13 bytes

…(ÿ)…(()∞„()©:®Q

Porto de @ETHproductions resposta Japt 's para corrigir o caso de teste()(()()(()())(()())) .
-2 bytes graças a @Adnan .

Com base neste comentário do OP , agora uso ()como valor verdadeiro e qualquer outra coisa como falsey. Se ambos os valores precisarem ser consistentes em vez de apenas um, seria a resposta antiga de 16 bytes ( …(ÿ)…(()∞„()©:®Q), retornando 0para 1os casos de teste truthy e falsey.

Experimente online ou verifique todos os casos de teste .

Explicação

…(ÿ)             # Take the input (implicitly) and surround it with "(" and ")"
            :    # Infinite replacement of:
    …(()∞        #  "(()())"    ("(()" mirrored)
         „()     #  with "()"
                 # After the infinite replacement: return the result
                 # ("()" for truthy; falsey otherwise)

(Resposta antiga de 18 bytes que falhou no caso de teste ()(()()(()())(()()))..):

ΔD„()∞©6∍å_i®õ.:]Ā

Experimente online ou verifique todos os casos de teste .

Kevin Cruijssen
fonte
Eu acho que você pode usar o infinito método replace: „()∞õ:g_.
Adnan
sem esperar eu entendi mal o desafio
Adnan
@ Adnan Eu também pensava assim, mas falha nos casos de teste (()()()())que devem retornar falsey. Todo grupo de parênteses deve conter exatamente 0 ou 2 grupos internos.
Kevin Cruijssen
1
Você pode substituir '(®')Jpor …(ÿ).
Adnan
@Adnan Thanks! Eu sabia que ÿexistia, mas nunca o usei antes, esqueci completamente.
Kevin Cruijssen
2

Prolog , 46 bytes

a-->p,p.
a-->[].
p-->[l],a,[r].
f(X):-a(X,[]).

Experimente online!ou Verifique todos os casos de teste!

Usa listas de ler como entrada, por exemplo, "()()"é testado comof([l,r,l,r]). .

As três primeiras linhas são a gramática de cadeias válidas na sintaxe de gramática de cláusula definida do Prolog . a(A,B).retorna truequando Aé uma lista que segue a gramática e Bestá vazia. Assim, a função principal fpega alguns Xe verifica se a(X,[])mantém.

Laikoni
fonte
2

Python 2 , 73 71 bytes

f=lambda s,P='(()())':P in s and f(s.replace(P,'()'))or s in['()()','']

Experimente online!

Chas Brown
fonte
1

brainfuck, 50 bytes

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

Formatado:

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

Espera uma sequência de (e )sem uma nova linha à direita e gera saída \x01para true e \x00false. (Para legibilidade, você pode por exemplo, adicionar 48 +s antes da final .para torná-lo imprimir 1e 0em vez disso.)

Experimente online

Isso mantém uma pilha com o número de grupos em cada profundidade, distinguindo caracteres por paridade e verificando se o número de grupos está em {0, 2} após cada parêntese próximo; se a condição não for atendida, consome o restante da entrada e define um sinalizador; depois verifica a condição novamente no final do programa.

Se for permitido encerrar o fluxo de entrada com um caractere ímpar, podemos omitir a verificação final <[--[>->]]para salvar 10 bytes. (E se\n não fosse inconvenientemente uniforme, eu poderia ter proposto essa variante como a resposta principal.)

(Também poderíamos economizar alguns bytes alterando o formato de saída \x00para verdadeiro e não \x00falso, o que parece ser permitido (talvez acidentalmente) pela declaração do problema, como está escrita, mas, de qualquer forma, não seria muito interessante, e eu prefiro para não fazer essa alteração.)

Mitch Schwartz
fonte
1

Python2, 95 94 bytes

f=lambda i:g(eval("(%s)"%i.replace(")","),")))
g=lambda i:len(i)in(0,2)and all(g(j)for j in i)

Experimente online!

f () transforma a string em uma tupla aninhada, que passa para g ().

g () navega recursivamente a tupla e retorna False se algum elemento não tiver exatamente 0 ou 2 filhos.

Salvou um byte usando a formatação de string.

Triggernometria
fonte
1

Stax , 13 11 bytes

₧aaS▐îî»Å·╢

Execute e depure

Salvei dois bytes quando percebi que as entradas podem coincidentemente ser avaliadas implicitamente como literais de matriz. Removendo as aspas duplas, a entrada é simplificada.

A idéia geral é avaliar a entrada como uma matriz literal e mapear recursivamente os elementos para verificar o equilíbrio entre parênteses. Se a afirmação final falhar, haverá um pop subsequente em uma pilha vazia. No stax, saltar com pilhas vazias imediatamente termina o programa.

Descompactado, não jogado e comentado, é assim.

        input is implicitly treated as array literals
L       wrap entire input stack in an array
G       jump to the trailing '}', and come back when done
}       terminate the program, the rest is a recursive call target
{Gm     map array on top of the stack by using the recursive call target
%       get the length of the mapped array
02\#    is the length one of [0, 2]?
|c      assert value is truthy, pop if not

Execute este

recursivo
fonte
1

Java 10, 99 96 95 83 bytes

s->{s="("+s+")";for(var p="";!p.equals(s);s=s.replace("(()())","()"))p=s;return s;}

Porta da minha resposta 05AB1E (também retorna ()como verdade e qualquer outra coisa como falsey).

Experimente online.

Explicação:

s->{                 // Method with String as both parameter and return-type
  s="("+s+")";       //  Surround the input-String between "(" and ")"
  for(var p="";      //  Previous-String, starting empty
      !p.equals(s)   //  Loop as long as the previous and current Strings differ
      ;              //    After every iteration:
       s=s.replace("(()())","()"))
                     //     Replace all "(()())" with "()"
    p=s;             //   Set the previous String with the current
  return s;}         //  Return the modified input-String
                     //  (if it's now "()" it's truthy; falsey otherwise)

return s;pode ser return"()".equals(s);se um resultado booleano real foi necessário.

Kevin Cruijssen
fonte
Você pode salvar um byte se você apenas verificar!s.contains("()()(")
Charlie
@ Charlie Obrigado, mas o código continha um bug de qualquer maneira, então tive que alterá-lo. Agora ele foi corrigido (para o último caso de teste adicionado de falsey) e jogou 4 bytes ao mesmo tempo.
Kevin Cruijssen