Verifica se una stringa è bilanciata tra parentesi


15

Chiamiamo un gruppo di parentesi il open paren (, il suo paren vicino vicino )e tutto al loro interno.

Un gruppo o una stringa di parentesi è chiamato parentesi bilanciata se contiene nulla o solo 2 gruppi di parentesi bilanciate parentesi.

Per esempio:

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.

Allo stesso modo:

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.

Pertanto, una stringa o un gruppo di parentesi bilanciati tra parentesi dovrebbe:

  • Non contenere nulla.
  • Oppure contiene solo ed esattamente 2 gruppi di parentesi bilanciate tra parentesi. Non dovrebbe contenere nient'altro.

Compito:

Il tuo compito è scrivere una funzione o un programma che controlli se una determinata stringa è una parentesi bilanciata o meno.

Ingresso:

L'input sarà una stringa o un elenco di caratteri o qualcosa di simile. Puoi presumere che la stringa sarà composta solo da caratteri '('e ')'. Puoi anche presumere che ogni parentesi aperta (abbia la corrispondente parentesi chiusa ), quindi non preoccuparti di stringhe come "((("o ")("o "(())("...

Nota: Come menzionato da @DigitalTrauma nel suo commento a soffietto, è ok per subtitute il ()combo da altri personaggi (come ad esempio <>, [], ...), se si tratta di causando lavoro in più, come la fuga in alcune lingue

Produzione:

Qualsiasi cosa per segnalare se la stringa è bilanciata tra parentesi o meno (vero o falso, 1 o 0, ...). Includi nella tua risposta ciò che la tua funzione / programma dovrebbe produrre.

Esempi:

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

Gli ultimi due esempi hanno davvero fatto la differenza!

Buona fortuna!


Qualcosa per segnalare se la stringa è bilanciata tra parentesi o meno È necessario un output coerente, ovvero solo due valori?
Luis Mendo,

@LuisMendo Potrebbero essere categorie. vale a dire valori di verità per segnalare la verità e valori di falsa per segnalare diversamente. Quindi potrebbe essercene di più, ma dovrebbe essere comunque coerente.
ibrahim mahrir,

1
Va bene se prendo un elenco binario come input? Ad esempio, "(()())()"sarebbe rappresentato come [0, 0, 1, 0, 1, 1, 0, 1]. Ciò eliminerebbe la necessità di convertire l'input in codice carattere e quindi sottrarre.
JungHwan Min


1
@WindmillCookies Non vedo come sia correlato a questo. Cose totalmente diverse. Anche il concetto è diverso.
Ibrahim Mahrir,

Risposte:


8

Japt v2, 20 byte

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

Provalo online!

Ognuno male la sfida in un primo e sebbene che ciascuna coppia di parentesi doveva contenere un ancor numero di sub-coppie, mentre in realtà la sfida effettivamente chiede 0 o 2 sub-coppie. Quindi ecco la mia risposta rivista, usando la stessa tecnica di prima.

Possiamo ancora risolvere la sfida con la sostituzione ricorsiva. Il fatto è, invece di rimuovere tutte le occorrenze di ()(), dobbiamo assicurarci che non ci sia nient'altro nello stesso wrapper oltre al ()()(in altre parole, no ()()()()o niente del genere). Possiamo farlo sostituendo ricorsivamente (()())con ().

Il nuovo problema è che l'input stesso non ha una coppia di parentesi esterne (in quanto ciò non lo renderebbe una stringa bilanciata tra parentesi), costringendoci a racchiuderlo in una coppia aggiuntiva per ridurlo completamente. Infine, il risultato finale per le stringhe bilanciate è ora ()invece della stringa vuota, quindi controlliamo l'uguaglianza piuttosto che prendere semplicemente il NOT logico dell'output.


7

sed 4.2.2, 30

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

Provalo online .

Ciò restituisce un codice di uscita della shell 1 per True e 0 per 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

7

Perl 5 -lp, 24 22 byte

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

Provalo online! Il link include casi di test. Modifica: salvato 2 byte grazie a @JoKing. Spiegazione: solo una regex ricorsiva. Il gruppo di acquisizione esterno rappresenta una stringa bilanciata come <seguita da una stringa bilanciata opzionale seguita da una >, due volte. Tieni presente che la maggior parte delle altre risposte è in grado di utilizzare ()s, ma ciò costa altri due byte:

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

Provalo online! Il link include casi di test.


3
Dato che puoi usare altre coppie di parentesi, puoi salvare due byte usando<>
Jo King il

1
@JoKing Quasi tutte le altre risposte sono state in grado di utilizzare ()s, quindi non pensavo fosse un confronto equo, tuttavia vedo che la risposta APL di @ ngn utilizza anche <>s, quindi ho aggiornato questo.
Neil,

6

6502 routine codice macchina , 48 byte

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

Si aspetta un puntatore a una stringa in $fb/$fc che dovrebbe contenere solo (e ). Cancella il flag C (Carry) se la stringa è "bilanciata in modo parantesco", la imposta diversamente (che è un tipico linguaggio sul 6502, imposta carry "on error"). Non fa nulla di sensato su input non validi.

Sebbene l'algoritmo sia ricorsivo, non si chiama se stesso (il che richiederebbe più byte e renderebbe dipendente la posizione del codice) ma mantiene invece una profondità di ricorsione stessa e utilizza la ramificazione "semplice".

Smontaggio commentato

; 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

Esempio di programma assemblatore C64 che utilizza la routine:

Demo online

immagine dello schermo

Codice nella sintassi 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

5

V , 21 , 20 byte

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

Provalo online! oppure Verifica tutti i casi di test!

é(                      " 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                                ^()$

Puoi spiegare il tuo codice così posso (si spera) trovare una testcase che non funziona, come ho fatto con la risposta di @Adàm .
Ibrahim Mahrir,

@ibrahimmahrir Done.
DJMcMayhem

5

Brachylog , 28 byte

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

Provalo online!

Spiegazione

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

4

C (gcc) , 113 byte

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

Provalo online!

Spiegazione

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

Provalo online!


3

MATL , 26 25 byte

oo~`tnw52B5LZttnb<]XB10X-

Provalo online!

Grazie alla risposta di @ETHProductions per l'idea "sostituisci (() ()) con ()" e al commento alla domanda di @JungHwan Min per l'idea di vedere le parentesi come cifre binarie.

L'output è un array vuoto per la verità, un numero positivo per la falsità - che penso sia consentito dal commento di OP: "Potrebbero essere categorie. Vale a dire valori di verità per segnalare la verità e valori di falsa per segnalare diversamente". In caso contrario, possiamo aggiungere nalla fine per +1 byte, per avere 0 come output di verità e 1 come output di falsa.

Con commenti:

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


3

Haskell , 82 59 byte

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

Provalo online!

Presumo che possa essere giocato a golf molto di più dato che è la mia prima volta a giocare a golf a Haskell, quindi qualsiasi trucco o commento è più che benvenuto.

MODIFICA - Grazie @nimi per aver salvato 23 byte (oltre il 28% dell'invio originale :)


1
Alcuni consigli: non c'è bisogno del ()giro y+1. Poiché sono consentite funzioni senza nome, è possibile rilasciare f=, r[0]è una funzione appropriata. Metti il ​​case base r b[]alla fine e passa a una funzione infix (diciamo #), quindi puoi usare b#_=. È inoltre possibile modificare leggermente l'algoritmo creando l'elenco per controllare se 0e 2s passo dopo passo invece di trasportarlo attorno alle chiamate di rin un accumulatore r(x:y:z) ... = x : r (...) acon case base r b [] = b. Esegui il controllo dopo la chiamata iniziale r[0]. Tutto sommato 73 byte.
nimi,


1
... o ancora meglio: rimani con l'accumulatore e passa a foldl (59 byte): provalo online! .
nimi,

@nimi Grazie mille, esattamente il tipo di consigli che stavo cercando :)
Vincent

3

JavaScript (ES6), 63 byte

Accetta input come una matrice di caratteri. Restituisce false per parentesi equilibrata, true per non parentesi bilanciata.

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

Provalo online!

Commentate

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

Ricorsivo, 54 byte

L'uso di sostituzioni ricorsive (come nella risposta Japt di ETHproductions ) è tuttavia significativamente più breve.

Accetta l'input come stringa. Restituisce 1 per la parentesi bilanciata, 0 per la parentesi non bilanciata.

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

Provalo online!


Ricorsivo, 46 ​​byte

Questo genera un errore di ricorsione per il bilanciamento non tra parentesi:

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

Provalo online!


Non sono così bravo in JavaScript, ma x [k] = - ~ x [k ++] può essere sostituito con x [k] ++; k ++ o anche ++ x [k ++]?
Андрей Ломакин,

2
@ АндрейЛомакин No, perché x[k]inizialmente non è definito e x[k]++darebbe NaN, mentre -~undefined1.
Arnauld,

@ АндрейЛомакин Adesso sto riutilizzando l'array di input, quindi a[k]inizialmente contiene un carattere. Ma la stessa logica si applica alle stringhe: applicare l' ++operatore su di esse produce NaN, ma gli operatori bit a bit (come ~) obbligano ad essere costretti a essere costretti in 0anticipo.
Arnauld,

Porta javascript a un livello completamente nuovo. : D
ibrahim mahrir,

3

Perl 6 ,  43 41  37 byte

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

Provalo

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

Provalo

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

Provalo

Allargato:

{  # 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
    /
}

3

R , 71 byte

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

Provalo online!

  • porting della soluzione ricorsiva Japt di @ETHproductions
  • -2 byte grazie a @JayCe

Un'altra soluzione, più lunga, ma interessante per il diverso approccio

R , 85 byte

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

Provalo online!

Spiegazione :

Prendi la stringa di input e sostituisce:

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

quindi valuta l'espressione risultante. Se è uguale a zero è bilanciato, altrimenti non lo è. L'uso di sumè necessario solo per gestire il caso stringa vuota, poiché la sua valutazione ritornaNULL .

per esempio

()(()()) => (2+-1)-(2+(2+-1)-(2+-1)-1) = 0
(()())   => (2+(2+-1)-(2+-1)-1)        = 1

Salva due byte:f=function(s,r=sub('(()())','()',s,f=T))'if'(r==s,s==''|s=='()()',f(r))
JayCe

Dovresti mettere prima la soluzione più breve
solo ASCII

@ Solo ASCII: hai ragione, ma dal momento che è fondamentalmente il porting di un'altra soluzione sembrava "rubare": P
digEmAll

3
@digEmAll Beh, in un sacco di sfide qui la maggior parte delle sfide fanno solo porta un'altra soluzione
ASCII-solo


2

05AB1E , 18 16 13 byte

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

Porto di @ETHproductions Japt risposta s' per risolvere il caso di test ()(()()(()())(()())).
-2 byte grazie a @Adnan .

Sulla base di questo commento di OP ora uso ()come valore di verità e qualsiasi altra cosa come falso. Se entrambi i valori devono essere coerenti anziché solo uno, si tratterebbe invece della vecchia risposta a 16 byte ( …(ÿ)…(()∞„()©:®Q), che restituisce 0per casi di verità e 1falsità.

Provalo online o verifica tutti i casi di test .

Spiegazione

…(ÿ)             # 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)

(Risposta di 18 byte precedente non riuscita per il caso di test ()(()()(()())(()()))..):

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

Provalo online o verifica tutti i casi di test .


Penso che si possa utilizzare l'infinito metodo replace: „()∞õ:g_.
Adnan,

no wait ho frainteso la sfida
Adnan

@Adnan All'inizio l'ho pensato anch'io, ma fallisce per i casi di test contenenti i (()()()())quali dovrebbe restituire falsey. Ogni gruppo di parentesi deve contenere esattamente 0 o 2 gruppi interni.
Kevin Cruijssen,

1
È possibile sostituire '(®')Jcon …(ÿ).
Adnan,

@Adnan Grazie! Sapevo ÿesistesse, ma non l' ho mai usato prima, quindi me ne sono completamente dimenticato.
Kevin Cruijssen,


2

Prolog , 46 byte

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

Provalo online! oppure Verifica tutti i casi di test!

Utilizza liste di le rcome input, ad es. "()()"Viene testato come f([l,r,l,r])..

Le prime tre righe sono la grammatica delle stringhe valide nella sintassi della grammatica della clausola definita di Prolog . a(A,B).ritorna truequando Aè un elenco che segue la grammatica ed Bè vuoto. Quindi la funzione principale ne fprende alcune Xe controlla se è a(X,[])valida.



1

Brainfuck, 50 byte

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

formattato:

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

Si aspetta una stringa di (e )senza una nuova riga finale e restituisce \x01true e \x00false. (Per motivi di leggibilità, ad esempio è possibile aggiungere 48 +s prima della finale .per farlo stampare 1e 0invece.)

Provalo online

Ciò mantiene uno stack con il numero di gruppi a ciascuna profondità, distinguendo i caratteri per parità e controllando se il numero di gruppi è in {0, 2} dopo ciascuna parentesi stretta; se la condizione non è soddisfatta, consuma il resto dell'input e imposta un flag; quindi controlla nuovamente la condizione alla fine del programma.

Se ci è permesso di terminare il flusso di input con un carattere dispari, possiamo omettere il controllo finale <[--[>->]]per salvare 10 byte. (Se\n non fosse stato anche inopportuno, avrei potuto proporre questa variante come risposta principale.)

(Potremmo anche salvare alcuni byte modificando il formato di output in \x00per true e non \x00per false, che sembra essere consentito (forse accidentalmente) dall'istruzione del problema come scritto, ma comunque non sarebbe molto interessante e preferisco di non apportare quel cambiamento.)


1

Python2, 95 94 byte

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

Provalo online!

f () trasforma la stringa in una tupla nidificata, che passa a g ().

g () naviga in modo ricorsivo nella tupla e restituisce False se un elemento non ha esattamente 0 o 2 figli.

Salvato un byte utilizzando la formattazione della stringa.


1

Stax , 13 11 byte

₧aaS▐îî»Å·╢

Esegui ed esegui il debug

Ho salvato due byte quando ho capito che gli input possono essere casualmente evitati implicitamente come array letterali. Rimuovendo le doppie virgolette, l'input è semplificato.

L'idea generale è di valutare l'input come un array letterale e mappare ricorsivamente gli elementi per verificare l'equilibrio parethesly. Se l'asserzione finale dovesse mai fallire, allora ci sarà un pop successivo su uno stack vuoto. In stax, saltar fuori con pile vuote termina immediatamente il programma.

Disimballato, non golfato e commentato, sembra così.

        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

Esegui questo


1

Java 10, 99 96 95 83 byte

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

Porta della mia risposta 05AB1E (quindi ritorna anche() come verità e qualsiasi altra cosa come falsità).

Provalo online.

Spiegazione:

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;può essere return"()".equals(s);se fosse richiesto un risultato booleano effettivo.


Puoi salvare un byte se controlli!s.contains("()()(")
Charlie

@Charlie Grazie, ma il codice conteneva comunque un bug, quindi ho dovuto cambiarlo. Ora è stato risolto (per l'ultimo caso di prova del falso aggiunto) e giocato a golf di 4 byte contemporaneamente.
Kevin Cruijssen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.