Tester si une chaîne est équilibrée entre parenthèses


15

Nous appelons un groupe de parens le paren ouvert (, son paren proche correspondant )et tout ce qu'il contient .

Un groupe ou une chaîne de parens est appelé équilibré entre parenthèses s'il ne contient rien ou seulement 2 groupes de parens équilibrés entre parenthèses.

Par exemple:

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.

Également:

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.

Ainsi, une chaîne ou un groupe de parenthèses équilibré entre parenthèses devrait:

  • Ne contient rien du tout.
  • Ou contenir seulement et exactement 2 groupes de parens équilibrés entre parenthèses. Il ne doit contenir rien d'autre.

Tâche:

Votre tâche consiste à écrire une fonction ou un programme qui vérifie si une chaîne donnée est équilibrée entre parenthèses ou non.

Contribution:

L'entrée sera une chaîne ou une liste de caractères ou quelque chose de similaire. Vous pouvez supposer que la chaîne ne comprendra que les caractères '('et ')'. Vous pouvez également supposer que chaque paren ouvert (aura son paren proche correspondant ), alors ne vous inquiétez pas pour les chaînes comme "((("ou ")("ou "(())("...

Note: Comme mentionné par @DigitalTrauma dans son commentaire ci - dessous, il est autorisé à subtitute le ()combo par d' autres caractères ( par exemple <>, []...), si elle est à l' origine du travail supplémentaire pour fuir dans certaines langues

Production:

N'importe quoi pour signaler si la chaîne est équilibrée entre parenthèses ou non (vrai ou faux, 1 ou 0, ...). Veuillez inclure dans votre réponse ce que votre fonction / programme devrait générer.

Exemples:

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

Les deux derniers exemples ont vraiment fait la différence!

Bonne chance!


N'importe quoi pour indiquer si la chaîne est équilibrée entre parenthèses ou non. Une sortie cohérente est-elle requise, c'est-à-dire seulement deux valeurs?
Luis Mendo

@LuisMendo Pourrait être des catégories. c'est-à- dire des valeurs véridiques pour signaler la véracité et des valeurs fausses pour signaler le contraire. Il pourrait donc y en avoir plus, mais cela devrait néanmoins être cohérent.
ibrahim mahrir

1
Est-ce correct si je prends une liste binaire en entrée? Par exemple, "(()())()"serait représenté comme [0, 0, 1, 0, 1, 1, 0, 1]. Cela supprimerait la nécessité de convertir l'entrée en code de caractères, puis de la soustraire.
JungHwan Min


1
@WindmillCookies Je ne vois pas comment cela est lié à celui-ci. Des choses totalement différentes. Même le concept est différent.
ibrahim mahrir

Réponses:


8

Japt v2, 20 octets

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

Testez-le en ligne!

Tout le monde a mal compris le défi au début et même si chaque paire de parenthèses devait contenir un nombre pair de sous-paires, alors qu'en fait le défi demande en fait 0 ou 2 sous-paires. Voici donc ma réponse révisée, en utilisant la même technique que précédemment.

Nous pouvons toujours résoudre le problème avec le remplacement récursif. Le fait est qu'au lieu de simplement supprimer toutes les occurrences de ()(), nous devons nous assurer qu'il n'y a rien d'autre dans le même wrapper que le ()()(en d'autres termes, aucun ()()()()ou quelque chose comme ça). Nous pouvons le faire en remplaçant récursivement (()())par ().

Le nouveau problème est que l'entrée elle-même n'a pas une paire de parenthèses externes (car cela ne ferait pas d'elle une chaîne équilibrée entre parenthèses), nous forçant à l'envelopper dans une paire supplémentaire pour la réduire complètement. Enfin, le résultat final pour les chaînes équilibrées est maintenant à la ()place de la chaîne vide, nous vérifions donc l'égalité plutôt que de simplement prendre le NON logique de la sortie.


7

sed 4.2.2, 30

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

Essayez-le en ligne .

Cela renvoie un code de sortie du shell de 1 pour True et de 0 pour 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 octets

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

Essayez-le en ligne! Le lien inclut des cas de test. Edit: sauvé 2 octets grâce à @JoKing. Explication: juste une expression rationnelle récursive. Le groupe de capture externe représente une chaîne équilibrée en tant que <suivie d'une chaîne équilibrée facultative suivie de >deux fois. Notez que la plupart des autres réponses peuvent utiliser ()s mais cela coûte deux octets supplémentaires:

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

Essayez-le en ligne! Le lien inclut des cas de test.


3
Puisque vous pouvez utiliser d'autres paires de crochets, vous pouvez économiser deux octets en utilisant<>
Jo King

1
@JoKing Presque toutes les autres réponses ont pu utiliser ()s, donc je ne pensais pas que c'était une comparaison juste, mais je vois que la réponse APL de @ ngn utilise également <>s donc j'ai mis à jour celle-ci.
Neil

6

6502 routine de code machine , 48 octets

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

Attend un pointeur sur une chaîne dans $fb/ $fcqui ne devrait contenir que (et ). Efface l'indicateur C (Carry) si la chaîne est "équilibrée entre parenthèses", le définit autrement (ce qui est un idiome typique sur le 6502, définissez le portage "en cas d'erreur"). Ne fait rien de sensé sur une entrée invalide.

Bien que l'algorithme soit récursif, il ne s'appelle pas lui-même (ce qui nécessiterait plus d'octets et rendrait la position du code dépendante), mais maintient à la place une profondeur de récursivité elle-même et utilise une ramification "simple".

Démontage commenté

; 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

Exemple de programme assembleur C64 utilisant la routine:

Démo en ligne

screenshot

Code dans la syntaxe 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 octets

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

Essayez-le en ligne! ou Vérifiez tous les cas de 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                                ^()$

Pouvez-vous expliquer votre code afin que je puisse (espérons-le) trouver un testcase qui ne fonctionne pas, comme je l'ai fait avec la réponse de @ Adàm .
ibrahim mahrir

@ibrahimmahrir Terminé.
DJMcMayhem

5

Brachylog , 28 octets

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

Essayez-le en ligne!

Explication

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

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

Essayez-le en ligne!

Explication

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

Essayez-le en ligne!


3

MATL , 26 25 octets

oo~`tnw52B5LZttnb<]XB10X-

Essayez-le en ligne!

Merci à la réponse de @ETHProductions pour l'idée "remplacer (() ()) par ()" et au commentaire de la question de @JungHwan Min pour l'idée de voir les crochets comme des chiffres binaires.

La sortie est un tableau vide pour la vérité, un nombre positif pour falsey - ce qui, je pense, est autorisé par le commentaire de OP: "Cela pourrait être des catégories. Si ce n'est pas le cas, nous pouvons ajouter nà la fin pour +1 octet, pour avoir 0 comme sortie véridique et 1 comme sortie falsey.

Avec commentaires:

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 octets

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

Essayez-le en ligne!

Je suppose qu'il peut être joué beaucoup plus loin, car c'est la première fois que je joue au golf à Haskell, donc toutes les astuces ou commentaires sont les bienvenus.

EDIT - Merci @nimi pour avoir économisé 23 octets (plus de 28% de la soumission originale :)


1
Quelques conseils: pas besoin de faire le ()tour y+1. Comme les fonctions sans nom sont autorisées, vous pouvez supprimer la f=, r[0]est une fonction appropriée. Mettez le cas de base r b[]à la fin et passez à une fonction d'infixe (par exemple #), puis vous pouvez l'utiliser b#_=. Vous pouvez également modifier légèrement votre algorithme en créant la liste pour vérifier 0s et 2s étape par étape au lieu de la transporter autour des appels rdans un accumulateur r(x:y:z) ... = x : r (...) aavec cas de base r b [] = b. Faites la vérification après l'appel initial r[0]. En tout 73 octets.
nimi


1
... ou mieux encore: restez avec l'accumulateur et passez à foldl(59 octets): essayez-le en ligne! .
nimi

@nimi Merci beaucoup, exactement le genre de conseils que je cherchais :)
Vincent

3

JavaScript (ES6), 63 octets

Prend l'entrée comme un tableau de caractères. Renvoie false pour équilibré entre parenthèses, true pour non équilibré entre parenthèses.

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

Essayez-le en ligne!

Commenté

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

Récursif, 54 octets

L'utilisation de remplacements récursifs (comme dans la réponse Japt d'ETHproductions ) est cependant beaucoup plus courte.

Prend l'entrée sous forme de chaîne. Renvoie 1 pour équilibré entre parenthèses, 0 pour non équilibré entre parenthèses.

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

Essayez-le en ligne!


Récursif, 46 octets

Celui-ci lance une erreur de récursivité pour non équilibrée entre parenthèses:

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

Essayez-le en ligne!


Je ne suis pas très bon en JavaScript mais est-ce que x [k] = - ~ x [k ++] pourrait être remplacé par x [k] ++; k ++ ou même ++ x [k ++]?
Андрей Ломакин

2
@ АндрейЛомакин Non, car x[k]est initialement indéfini et x[k]++donnerait NaN, alors que -~undefineddonne 1.
Arnauld

@ АндрейЛомакин Je réutilise maintenant le tableau d'entrée, donc a[k]contient initialement un caractère. Mais la même logique s'applique aux chaînes: appliquer l' ++opérateur sur elles donne NaN, mais les opérateurs au niveau du bit (tels que ~) les forcent à être contraints au 0préalable.
Arnauld

Prend le javascript à un tout nouveau niveau. : D
ibrahim mahrir

3

Perl 6 ,  43 41  37 octets

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

Essaye-le

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

Essaye-le

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

Essaye-le

Étendu:

{  # 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 octets

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

Essayez-le en ligne!

  • portage de la solution Japt récursive de @ETHproductions
  • -2 octets grâce à @JayCe

Une autre solution - plus longue - mais intéressante pour l'approche différente

R , 85 octets

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

Essayez-le en ligne!

Explication:

Prenez la chaîne d'entrée et remplace:

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

évalue ensuite l'expression résultante. S'il est égal à zéro, il est équilibré, sinon ce n'est pas le cas. L'utilisation desum n'est nécessaire que pour gérer le cas de chaîne vide, car son évaluation revient NULL.

par exemple

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

Économisez deux octets:f=function(s,r=sub('(()())','()',s,f=T))'if'(r==s,s==''|s=='()()',f(r))
JayCe

Vous devez d'abord mettre la solution la plus courte
ASCII uniquement

@ ASCII uniquement: vous avez raison, mais comme il s'agit essentiellement d'un portage d'une autre solution, cela semblait "voler": P
digEmAll

3
@digEmAll Eh bien, dans de nombreux défis ici, la plupart des défis ne font que porter une autre solution
ASCII uniquement


2

05AB1E , 18 16 13 octets

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

Port de @ETHproductions Japt s » réponse fixer le cas de test ()(()()(()())(()())).
-2 octets grâce à @Adnan .

Sur la base de ce commentaire de l'OP, j'utilise maintenant() comme valeur véridique, et rien d'autre comme falsey. Si les deux valeurs doivent être cohérentes au lieu d'une seule, ce serait l'ancienne réponse de 16 octets à la place ( …(ÿ)…(()∞„()©:®Q), en retournant 0pour véridique et1 les cas de test falsey.

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication

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

(Ancienne réponse de 18 octets qui a échoué pour le cas de test ()(()()(()())(()())) ..):

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

Essayez-le en ligne ou vérifiez tous les cas de test .


Je pense que vous pouvez utiliser la méthode remplacer infinie: „()∞õ:g_.
Adnan

pas d'attente j'ai mal compris le défi
Adnan

@Adnan Je le pensais aussi au début, mais cela échoue pour les cas de test contenant (()()()()) qui devraient renvoyer Falsey. Chaque groupe de parenthèses doit contenir exactement 0 ou 2 groupes internes.
Kevin Cruijssen

1
Vous pouvez remplacer '(®')Jpar …(ÿ).
Adnan

@Adnan Merci! Je savais qu'il ÿexistait, mais je ne l'ai jamais utilisé auparavant, alors je l'ai complètement oublié.
Kevin Cruijssen


2

Prolog , 46 octets

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

Essayez-le en ligne!ou Vérifiez tous les cas de test!

Utilise des listes de l et ren entrée, par exemple "()()"est testé en tant que f([l,r,l,r])..

Les trois premières lignes sont la grammaire des chaînes valides dans la syntaxe de la grammaire de clause définie de Prolog . a(A,B).renvoie truequand Aest une liste qui suit la grammaire et Best vide. Ainsi la fonction principale en fprend Xet vérifie si elle a(X,[])est maintenue.



1

brainfuck, 50 octets

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

Formaté:

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

Attend une chaîne de (et )sans un retour à la ligne de fin, et affiche \x01vrai et \x00faux. (Pour plus de lisibilité, vous pouvez par exemple ajouter 48 +s avant la finale .pour le faire imprimer 1et0 place.)

Essayez-le en ligne

Cela maintient une pile avec le nombre de groupes à chaque profondeur, en distinguant les caractères par parité et en vérifiant si le nombre de groupes est dans {0, 2} après chaque parenthèse fermée; si la condition n'est pas remplie, consomme le reste de l'entrée et définit un indicateur; vérifie ensuite à nouveau la condition à la fin du programme.

Si nous sommes autorisés à terminer le flux d'entrée avec un caractère impair, nous pouvons omettre la vérification finale <[--[>->]]pour économiser 10 octets. (Si ce \nn'était même pas gênant, j'aurais peut-être proposé cette variante comme réponse principale.)

(Nous pourrions également économiser quelques octets en changeant le format de sortie \x00pour vrai et non \x00pour faux, ce qui semble être autorisé (peut-être accidentellement) par l'énoncé du problème tel qu'il est écrit, mais de toute façon ce ne serait pas très intéressant, et je préfère de ne pas faire ce changement.)


1

Python2, 95 94 octets

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

Essayez-le en ligne!

f () transforme la chaîne en un tuple imbriqué, qu'elle passe à g ().

g () parcourt récursivement le tuple et retourne False si un élément n'a pas exactement 0 ou 2 enfants.

Enregistré un octet en utilisant le formatage de chaîne.


1

Stax , 13 11 octets

₧aaS▐îî»Å·╢

Exécuter et déboguer

J'ai enregistré deux octets lorsque j'ai réalisé que les entrées peuvent être implicitement évallées comme des littéraux de tableau. En supprimant les guillemets doubles, l'entrée est simplifiée.

L'idée générale consiste à évaluer l'entrée en tant que littéral de tableau et à mapper récursivement les éléments pour vérifier l'équilibre parethesly. Si l'assertion finale échoue, il y aura ensuite un pop sur une pile vide. Dans stax, l'éclatement avec des piles vides met immédiatement fin au programme.

Déballé, non golfé et commenté, il ressemble à ceci.

        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

Exécutez celui-ci


1

Java 10, 99 96 95 83 octets

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

Port de ma réponse 05AB1E (retourne également() véridique et rien d'autre que falsey).

Essayez-le en ligne.

Explication:

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;peut être return"()".equals(s);si un résultat booléen réel était requis.


Vous pouvez enregistrer un octet si vous venez de vérifier!s.contains("()()(")
Charlie

@Charlie Merci, mais le code contenait quand même un bug, il fallait donc le changer. Il est maintenant corrigé (pour le dernier cas de test de falsey ajouté) et joué au golf de 4 octets en même temps.
Kevin Cruijssen
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.