Le parentesi sono abbinate completamente?


56

È necessario scrivere un programma o una funzione che accetta una stringa di parentesi e genera se la stringa è completamente abbinata. Il programma dovrebbe stampare un valore di verità o falsa e IO può essere in qualsiasi formato ragionevole .

Regole e definizioni:

  • Ai fini di questa sfida, una "staffa" è uno di questi personaggi: ()[]{}<>.

  • Una coppia di parentesi è considerata "abbinata" se le parentesi aperta e chiusa sono nell'ordine giusto e non hanno caratteri al loro interno, come

    ()
    []{}
    

    O se anche ogni sottoelemento al suo interno è abbinato.

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

    I sottoelementi possono anche essere nidificati a più livelli di profondità.

    [(){<><>[()]}<>()]
    <[{((()))}]>
    
  • Una stringa è considerata "Completamente abbinata" se e solo se:

    1. Ogni singolo personaggio è una parentesi,

    2. Ogni coppia di staffe ha la staffa di apertura e chiusura corretta e nel giusto ordine, e

    3. Ogni parentesi è abbinata.

  • Si può presumere che l'input conterrà solo ASCII stampabile .

Test IO

Ecco alcuni input che dovrebbero restituire un valore di verità:

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

E qui ci sono alcuni output che dovrebbero restituire un valore 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.

Come al solito, si tratta di code-golf, quindi si applicano scappatoie standard e vince la risposta più breve in byte.



7
Nota per i potenziali elettori vicini: la sfida che ho collegato include anche un ordine di priorità per i tipi di parentesi in modo che non possano essere nidificati in un ordine arbitrario. Penso che lo renda sufficientemente diverso.
Martin Ender,

È [}una partita? E se no, dove è escluso da queste regole?
user207421

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

6
Valuterò la prima soluzione in Parentesi
Leo

Risposte:


17

05AB1E , 19 byte

L'input è riportato tra virgolette . Codice:

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

Bene, sono stati trovati un sacco di bug e funzionalità non implementate. Spiegazione:

"[](){}<>"           # 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

Questa è in realtà una parte difficile. Come appare in pseudocodice è:

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

Questo è coperto da questa parte dal codice 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)

Come puoi vedere, si tratta di una sostituzione infinita (eseguita fino a quando la stringa non cambia più). Quindi, non devo preoccuparmi di impostare la sostituzione in un ciclo, poiché questo è già incorporato. Dopo di che:

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

Utilizza la codifica CP-1252 . Provalo online! (leggermente modificato perché la versione precedente è obsoleta).


1
Ben giocato a golf!
SamyQc,

1
È õstato aggiunto prima ?
Zacharý,

@ Zacharý Sì, è corretto
Adnan,

33

Brain-Flak , 1101, 1085 , 981 byte

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

Provalo online!

Si tratta di 980 byte di codice sorgente e +1per il -aflag che consente input ASCII (ma output decimale)

Questa è una risposta che volevo scrivere da molto tempo. Almeno 6 mesi Ho aspettato di postare questo perché sapevo che rispondere a questa sfida sarebbe stato molto più difficile con la scossa cerebrale. Ma ne vale la pena per un motivo molto importante: il codice sorgente stesso è un input sincero, che è l'intero punto di questo linguaggio stesso.

E come ho scritto qui , questa domanda è stata ciò che mi ha ispirato a scrivere il cervello-flak.

Poco dopo aver scritto Le parentesi sono abbinate completamente ?, Mi sono chiesto quante informazioni puoi memorizzare solo con parentesi corrispondenti. Una cosa che mi ha colpito è che anche se hai solo 4 "atomi":

(){}[]<>

hai davvero 8 unità di informazione da trasmettere, dal momento che ognuno di questi tipi di parentesi può essere vuoto o avere altre parentesi tra loro, che sono fondamentalmente informazioni diverse. Così, ho deciso di scrivere una lingua che permettesse solo parentesi corrispondenti e dove parentesi vuote trasmettono qualcosa di diverso rispetto alle parentesi con altre parentesi al loro interno.

Questa risposta ha impiegato circa due ore per scrivere. Devo ammettere che è scarsamente golfato, soprattutto perché un sacco di codice viene ripetuto per ogni tipo di parentesi. Ma sono per lo più stupito di essere stato in grado di scrivere una risposta, soprattutto dato che Brain-Flak lo è

Un esolang minimalista progettato per essere doloroso da usare

Proverò a giocare a golf più tardi, ma volevo farlo comunque.

Ho una spiegazione dettagliata, ma è lunga circa 6000 caratteri, quindi penso che non sarebbe saggio incollare l'intera cosa in questa risposta. Puoi leggerlo qui se vuoi. Aggiungerò una spiegazione più breve qui.

L'idea di base è che ripetiamo i seguenti passaggi per ogni personaggio in pila:

  • Controlliamo ogni personaggio per vedere se corrisponde a una parentesi. Se si tratta di una parentesi quadra aperta, spingiamo un numero sull'altro stack in base alla seguente mappatura:

    ( = 1
    < = 2
    [ = 3
    { = 4
    
  • Quindi controlliamo per vedere se corrisponde a qualsiasi parentesi di chiusura. In tal caso, inseriamo il numero equivalente nello stack alternativo, proprio come per le parentesi aperte. Quindi , controlliamo se i primi due numeri sono uguali. In tal caso, entrambi vengono visualizzati e il programma continua normalmente. In caso contrario, eliminiamo entrambe le pile (per interrompere il looping) e ne inseriamo una sulla pila alternativa. Questa è essenzialmente un'istruzione "break".

  • Dopo aver verificato gli 8 tipi di parentesi, spingiamo il valore di questa corsa attraverso il ciclo. Dato che azzeriamo la maggior parte di esso, gli unici frammenti che hanno un valore sono i condizionali quando confrontiamo tra parentesi. Quindi, se una parentesi viene abbinata, l'intero loop ha un valore di 1. Se nessuno di loro ha fatto, l'intero loop ha un valore di 0. In questo caso, elimineremo entrambi gli stack e sposteremo uno 0 sullo stack alternativo. Ancora una volta, questo è come un'istruzione "break".

Dopo che questo ciclo principale è in esecuzione, il resto è abbastanza semplice. Siamo nella pila principale (vuota) e la pila alternativa è vuota (se le parentesi erano abbinate) o non vuota se non lo fossero. Quindi eseguiamo questo:

#Toggle to the alternate stack
<>

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

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

Questo spingerà uno 0 o un 1 nello stack principale e quando il programma termina viene implicitamente stampato.



revisioni

  • Rimossa la ridondanza push pop

  • Modificata la mia logica del contatore zero


1
Awwwwwweeeeesommmmeeeee!
Arjun,

23

Brain-Flak , 204 196 190 byte

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

Provalo online!

-8 byte grazie a Wheat Wizard. -6 byte grazie a Jo King.

Spiegazione

Questo programma memorizza i codici carattere di tutte le parentesi non chiuse correnti sul secondo stack. Le coppie di parentesi <>, []e {}hanno ciascuno codici carattere che differiscono con esattamente 2, quindi non c'è alcuna necessità di controllare appositamente. La coppia ()differisce solo di 1, quindi controlliamo in modo (specifico ed effettivamente diminuiamo quel byte (incrementando effettivamente ogni altro byte) prima di continuare.

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

"Logico non di differenza" (noto anche come uguale a) potrebbe essere più breve di([{}]<>({}))((){[()](<{}>)}{})
Mago del grano,

Penso che puoi sostituire l'ultimo controllo con ({<>[()]}())-6 byte
Jo King

@JoKing Grazie. Non credo che l'avrei mai notato.
Nitrodon,

Sì, l'ho capito nella mia risposta e mi sono reso conto che era applicabile anche alla tua
Jo King

13

JavaScript (ES6), 52 50 byte

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

Rimuovere ripetutamente le parentesi fino a quando il risultato è lo stesso dell'originale, quindi restituire false a meno che la stringa non sia vuota.

Modifica: salvato 2 byte grazie a @ edc65.



11

CJam, 25 24 23 21 byte

Grazie a Sp3000 per aver salvato 2 byte.
Grazie a jimmy23013 per aver salvato 2 byte.

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

Suite di test.

Funziona essenzialmente lo stesso come le altre risposte: abbiamo ripetutamente togliamo (), [], <>e {}dalla stringa e controlliamo se si finisce con la stringa vuota. Per evitare di dover controllare quando abbiamo finito, rimuoviamo le coppie Nvolte dov'è Nla lunghezza della stringa, che è sempre sufficiente (poiché ogni iterazione rimuoverà almeno due caratteri, a meno che non abbiamo finito). Sono felice di vedere che questo non batte Retina. :) (Anche se Pyth o Jelly potrebbero ...)

C'è un divertente trucco da golf qui: per ottenere la corda ()<>[]{}utilizziamo quanto segue:

{()<>}a`$

Il, {()<>}è solo un blocco (cioè una funzione), che contiene le altre parentesi come codice. Con aavvolgiamo il blocco in un array. Il `stringify quella matrice, che dà "[{()<>}]". Infine, ordiniamo la stringa con $, che riordina le parentesi ()<>[]{}.


Non ho familiarità con la tua lingua, ma la tua descrizione del tuo trucco da golf fa sembrare ()<>[]{}`che funzioni altrettanto bene, ed abbia lo stesso numero di byte, giusto?
Mooing Duck,

1
@MooingDuck No perché ()<>sono quattro operatori (decremento, incremento, quindi confronto o troncamento a seconda degli operandi), che verrebbero eseguiti immediatamente, mentre {}indica un blocco (l'equivalente di una funzione di CJam), ovvero un pezzo di codice che viene appena premuto nello stack senza valutarlo immediatamente. Ecco perché ho bisogno {}di racchiudere ()e <>, ma poi usare aper mettere tutto in un array è più corto di [...].
Martin Ender,

10

Python, 67 byte

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

Genera ed elimina un'espressione che sembra

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

e controlla se il risultato è vuoto.

Sp3000 ha salvato 8 byte sottolineando che [],(),{}può essere inserito senza virgolette perché sono oggetti Python e che due parentesi non sono necessarie.


8

Yacc, 119 byte

Non utilizza regex / sostituisci.

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

Compilazione

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

uso

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

7

Pyth, 31 25 24 byte

Golfato fino a 25 byte grazie a FryAmTheEggMan rimosso 1 byte

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

Provalo qui: suite di test !

Sono ancora un principiante di Pyth, ogni aiuto è apprezzato.

Spiegazione

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

A proposito, complimenti per l'altra risposta Pyth (che attualmente è di 20 byte)


Benvenuti in Puzzle di programmazione e Code Golf!
Adnan,

@Adnan Grazie! Questo è il mio primo golf!
FliiFe

Bel primo golf! Con un po 'risistemare e roba del genere, si può arrivare a 25: Vz=:z"<>|\[]|{}|\(\)"k;!z. In particolare, in pratica non è necessario utilizzare lse non si ha effettivamente bisogno del numero e =si indovina automaticamente la prima variabile utilizzata in un'espressione. Fammi sapere se vuoi che ti spieghi qualcos'altro nella chat di
Pyth

@FryAmTheEggman Grazie! Non sapevo che non lfosse necessario, è buono a sapersi. All'inizio, ho dichiarato una funzione perché la mia logica era diversa e ho dimenticato di rimuoverla. Devo includere la tua risposta alla mia? (Sono un novizio>. <)
FliiFe

3
In genere, se è pubblicato in un commento, l'autore del commento desidera che tu lo usi. Quindi vai avanti! :)
FryAmTheEggman,

6

Pyth, 20 byte

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

Provalo online: Test Suite

Rimuove Ripetutamente occorrenze di [], (), <>e {}dalla scissione e ri-fusione. Verifica se la stringa risultante è vuota o meno.


4

Javascript ES6, 54 byte

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

Utilizza un'implementazione di sostituzione ricorsiva. Abbastanza semplice.



4

Perl, 34 33 byte

Include +2 per -lp

Esegui con input su STDIN:

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

brackets.pl:

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

Trova la prima coppia di parentesi quadre senza nulla tra loro e la rimuove finché ce ne sono. Quindi controlla se la stringa finale è vuota.


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

Sarebbe bello se anche tu potessi fornire spiegazioni.
Prashant Pokhriyal,

@Dada Certo. Devo diventare senile ..
Ton Hospel,

4

Brain-Flak , 204 byte

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

Provalo online!

Non abbastanza breve come la risposta di Nitroden , ma utilizza un approccio molto diverso. Questo scorre ripetutamente l'input, rimuovendo ogni volta coppie di parentesi corrispondenti corrispondenti fino a quando non ne rimangono più. A quel punto se è rimasto qualcosa nello stack, la stringa non è stata completamente abbinata.

Spiegazione:

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

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

formattato:

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

Prevede input senza una nuova riga finale. Stampa \x00per falso e \x01vero.

Provalo online.

Approccio: mantenere uno stack a partire da \x01e premere la staffa di chiusura corrispondente ogni volta che si incontra una staffa di apertura. Prima di verificare se il personaggio corrente è una parentesi quadra aperta, controlla se è uguale alla parentesi quadra chiusa nella parte superiore della pila e, in tal caso, pop. Se non è né la parentesi di chiusura corretta né una parentesi di apertura, consumare il resto dell'input mentre si sposta il puntatore verso destra. Alla fine, controlla se il puntatore si trova accanto all'iniziale \x01.


2

Grime v0.1, 34 byte

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

Stampa 1per una partita e 0per nessuna partita. Provalo online!

Spiegazione

Grime è il mio linguaggio 2D di abbinamento dei modelli progettato per questa sfida ; può anche essere usato per abbinare stringhe 1D. Questa è la mia prima risposta con esso. Ho modificato Grime oggi, ma solo per cambiare il carattere di un elemento di sintassi ( `anziché ,), quindi non influisce sul mio punteggio.

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 byte, non competitivo

Provalo qui!

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/

C'è un po 'più di golf da fare, ma almeno funziona. Ho aggiunto un comando ðper tenere traccia delle pile dopo questa sfida in modo che ciò sia possibile / facilmente da remoto. Lo spiegherò tra poco, ma generalmente tiene traccia di tutte le stringhe ripetute e cerca ripetizioni; se c'è una ripetizione, allora la stringa è irriducibile. Altrimenti, la stringa verrà ridotta alla stringa / stack vuota e verrà emessa 1. Altrimenti, non verrà prodotto alcun output.


2

PowerShell v2 +, 63 62 byte

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

Non riesco a catturare JavaScript, ma al momento sta eliminando gli altri non-esolang.

Approccio simile come altre risposte: un semplice ciclo che continua fino a quando siamo in grado di rimuovere uno dei [], ()o <>(con diversi caratteri estranei perché abbiamo bisogno di sfuggire alle offerte speciali regex). Usiamo $bcome aiuto lungo la strada per ricordare come $aera impostato il nostro ciclo precedente . Una variabile non inizializzata è $null, quindi la prima volta che si incontra il loop, $aovviamente non è uguale a $null.

Alla fine del ciclo, $aè vuoto o no e il valore booleano di quella stringa è Trueo False.

Esempio

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 byte

Rasato di 8 byte grazie 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 uno stack.


Mi piace il c%7&2. In realtà, non è necessario k. Invece, puoi semplicemente incrementare la posizione ida modificare, kpoiché in ogni caso devi verificare se iè zero. Qualcosa di simile (codice non testato): 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 - L'incremento funzionerà? Dobbiamo anche evitare di iscrivere l'array con un valore negativo, quindi dobbiamo testare i o k in for.
mIllIbyte

Ah capisco C'è ancora spazio per miglioramenti:a[99],i,k;main(c){for(;read(0,&c,!k);c%7&2?k|=a[i--]^c/9:(a[++i]=c/9))k|=!strchr("()[]{}<>",c);putchar(48+!i*!k);}
xsot

@xsot - Grazie! Per riassumere i risparmi, leggi 5 byte salvati, ^ uno salvato e l'operando intermedio dell'operatore condizionale salvato 2. Sono sorpreso che l'operando intermedio dell'operatore condizionale possa essere un incarico. Ho pensato che ci sarebbe stato un errore, qualcosa del tipo "missing: before =".
mIllIbyte

@xsot - Ho provato ad incrementare i invece di usare k, come hai suggerito per la prima volta: 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);}ma questo non funziona ancora per input come ())), dato che il "popping" dallo stack in realtà non azzera i valori nell'array.
mIllIbyte,

2

Java 7, 156 151 byte

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

Non mi aspetto che questo vinca alcun premio, ma non ho ancora visto una risposta Java. Inoltre, mi piace nascondermi su PPCG e mi piacerebbe poter votare / commentare altre risposte.

L'immissione viene fornita come parametri del programma. Questo segue lo stesso formato di molte altre risposte qui in quanto preforma una sostituzione regex in un ciclo. Inizialmente l'ho avuto un ciclo N volte dove N è la lunghezza della stringa originale ma il ciclo a Integer.MAX_VALUEè più corto:]. Questo dovrebbe andare bene perché Integer.MAX_VALUEè la lunghezza massima di a Stringin Java, quindi c'è un'ipotesi implicita che la lunghezza dell'input sia qualcosa che è gestibile da Java. Il tempo di esecuzione è piuttosto scadente (ci sono voluti circa 20 minuti sul mio lappytop) a causa del loop ma non ho visto alcuna restrizione al riguardo.


2

Haskell , 151 byte

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

Provalo online!


Alcune cose: poiché la funzione (#)deve essere chiamata con la stringa vuota come secondo argomento, è necessario contare (#"")per il conteggio dei byte. Anche solo Truee Falsesono considerati veritieri / falsi, consultare la Guida alle regole del golf .
Laikoni,

1
Tuttavia, è possibile sostituire le quattro righe con le parentesi chiuse a:x#b:y|a==b=x#y, portando i byte a 113: Provalo online!
Laikoni,


2

Python 2.7, 96 byte

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

2
Benvenuti nel sito!
DJMcMayhem

1

Python 2, 80 byte

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

1

Julia, 51 byte

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

Il meno folle di diverse opzioni. Non sorprende che sfruttare la potenza di regex sia il percorso più breve per la corrispondenza delle stringhe, ma ciò si applica solo se il modello da abbinare è regolare. Provare a fare schemi ricorsivi PCRE finisce per gonfiare le dimensioni del codice, sia vedendo se l'intera stringa è la corrispondenza o ancorando le estremità e quindi creando un costrutto per specificare il corpo interno per la ricorsione regex. Nessuno dei due è carino o favorevole al codice golf.

Spiegazione:

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

La funzione rimuove ripetutamente coppie adiacenti di parentesi dal suo unico argomento e restituisce true se può derivare una stringa vuota in questo modo.


1

sed, 39 36 byte (34 per codice, 2 per -r)

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

Provalo online!

versione sed di quello che sembra essere l'approccio standard. Richiede espressioni regolari estese ( sed -r)

Salvato 3 byte grazie al ciarlatano Cows


È possibile rimuovere ais :ae tasalvare byte
Kritixi Lithos

@KritixiLithos Apparentemente quello era un bug in GNU sed che fu rimosso in 4.3 . Probabilmente lascerei cadere quei personaggi se questa voce fosse abbastanza vicina al leader per avere una possibilità di vincere, ma dato che non lo è, la lascerò nella forma più portatile in modo che non smetta di funzionare man mano che altri sistemi eseguono l'aggiornamento a 4.3.
Ray

1
Ripensandoci, sono sicuro che puoi rilasciare il qda /./e rilasciare anche le parentesi graffe. Provalo online! Questo a causa di come cfunziona l'
hange

@Cowsquack Grazie. Modificato.
Ray,

0

05AB1E, 9 byte

žu2ôõ:g2Q

L'input è riportato tra virgolette.

Provalo online!

Spiegazione:

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

Più a lungo anche delle risposte C e Brainfuck: o

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

Non usa regex, usa invece il primo carattere per determinare quale sia il tag di chiusura e trova il primo indice in cui quella parentesi è bilanciata (la somma cumulativa è zero). Quindi verifica iterativamente che ciò che è racchiuso tra parentesi e dopo le parentesi sia valido.

Devo vedere se esiste un approccio migliore ...


0

Lua , 295 byte

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

Versione 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

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

L'approccio qui è convertire la sequenza in codice R, quindi provare ad analizzarla e valutarla. Se questo dà un errore, quindi tornare FALSE.

Ma c'è un piccolo problema ... Le regole di R per le parentesi sono diverse, quindi <e >non sono affatto parentesi, e gli altri tipi hanno regole proprie. Ciò è risolto da un approccio rivoluzionario - una funzione di cigolio, la cui unica funzione è quella di segnalare un errore se la sua testa e la coda cigolano in modi diversi.

Ad esempio, []viene trasformato in S('[', {}, ']'), dove S è definito come ...

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

Poiché il cigolio della testa e il cigolio della coda corrispondono, non viene generato alcun errore.

Alcuni altri esempi (la parte sinistra è una sequenza di parentesi e la parte destra è la sua trasformazione in codice R valido che può essere valutato):

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

Alcune altre sequenze di parentesi comporteranno errori di analisi:

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

Quindi la parte rimanente rileva solo gli errori e restituisce FALSE se ce ne sono, e TRUE se non ce ne sono.

Il codice leggibile dall'uomo:

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

Applicandolo su casi campione:

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