Czy wsporniki są w pełni dopasowane?


56

Musisz napisać program lub funkcję, która pobiera ciąg nawiasów i wyświetla dane wyjściowe, niezależnie od tego, czy ten ciąg jest w pełni dopasowany. Twój program powinien wydrukować wartość prawdy lub fałszu , a IO może mieć dowolny rozsądny format .

Reguły i definicje:

  • Dla celów niniejszego wyzwanie, „uchwyt” jest każdy z tych znaków: ()[]{}<>.

  • Para nawiasów jest uważana za „dopasowaną”, jeśli nawiasy otwierające i zamykające są w odpowiedniej kolejności i nie zawierają w sobie znaków, takich jak

    ()
    []{}
    

    Lub jeśli każdy podelement w nim również jest dopasowany.

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

    Elementy podrzędne mogą być również zagnieżdżone na kilku warstwach.

    [(){<><>[()]}<>()]
    <[{((()))}]>
    
  • Ciąg jest uważany za „w pełni dopasowany”, tylko wtedy, gdy:

    1. Każda postać to nawias,

    2. Każda para wsporników ma prawidłowy wspornik otwierania i zamykania we właściwej kolejności, oraz

    3. Każdy wspornik jest dopasowany.

  • Możesz założyć, że dane wejściowe będą zawierały tylko ASCII do wydruku .

Przetestuj IO

Oto niektóre dane wejściowe, które powinny zwrócić prawdziwą wartość:

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

A oto kilka wyników, które powinny zwrócić wartość falsy:

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

Jak zwykle jest to gra w golfa, więc obowiązują standardowe luki i wygrywa najkrótsza odpowiedź w bajtach.



7
Uwaga dla potencjalnych bliskich wyborców: Wyzwanie, które połączyłem, obejmuje również kolejność priorytetów dla typów nawiasów, więc nie można ich zagnieżdżać w dowolnej kolejności. Myślę, że to czyni to wystarczająco innym.
Martin Ender,

Czy [}pasuje? A jeśli nie, to gdzie jest wykluczone przez te zasady?
user207421,

2
@EJP Nie, nie jest. Each pair of brackets has the correct opening and closing bracket and in the right order.
DJMcMayhem

6
Będę upvote pierwsze rozwiązanie w nawiasach
Leo

Odpowiedzi:


17

05AB1E , 19 bajtów

Dane wejściowe podano w cudzysłowie . Kod:

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

Bzdury, znaleziono wiele błędów i niezaimplementowanych funkcji. Wyjaśnienie:

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

To właściwie trudna część. Tak to wygląda w pseudokodzie:

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

Jest to objęte niniejszą częścią kodu 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)

Jak widać, jest to nieskończona zamiana (wykonywana do momentu, aż łańcuch się nie zmieni). Nie muszę się więc martwić ustawieniem zamiany w pętlę, ponieważ jest ona już wbudowana. Po tym:

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

Wykorzystuje kodowanie CP-1252 . Wypróbuj online! (nieznacznie zmodyfikowany, ponieważ powyższa wersja jest nieaktualna).


1
Ładnie grał w golfa!
SamyQc,

1
Czy to õbyło wcześniej dodane?
Zacharý

@ Zacharý Tak, to prawda
Adnan

33

Brain-Flak , 1101, 1085 , 981 bajtów

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

Wypróbuj online!

Jest to 980 bajtów kodu źródłowego i +1dla -aflagi zezwalającej na wejście ASCII (ale wyjście dziesiętne)

To jest odpowiedź, na którą chciałem napisać bardzo długiego czasu. Co najmniej 6 miesięcy. Czekałem, aby to opublikować, ponieważ wiedziałem, że odpowiedź na to wyzwanie będzie wyjątkowo trudna do opanowania. Ale warto z jednego bardzo ważnego powodu: sam kod źródłowy to prawdziwy wpis, który jest sednem samego tego języka.

I tak jak pisałem tym , to pytanie zainspirowało mnie do napisania flakera mózgu.

Krótko po tym, jak napisałem Czy nawiasy są w pełni dopasowane ?, zastanawiałem się, ile informacji można przechowywać tylko z dopasowanymi nawiasami. Jedną z rzeczy, które mnie wyróżniały, było to, że chociaż masz tylko 4 rodzaje atomów:

(){}[]<>

naprawdę masz do przekazania 8 jednostek informacji, ponieważ każdy z tych typów nawiasów może być pusty lub mieć inne nawiasy, które są zasadniczo różnymi informacjami. Postanowiłem więc napisać język, który dopuszcza tylko dopasowane nawiasy, a puste nawiasy przenoszą coś innego niż nawiasy z innymi nawiasami w środku.

Odpowiedź zajęła około dwóch godzin. Przyznaję, że jest dość słabo golfowy, głównie dlatego, że dla każdego typu nawiasu powtarzana jest duża część kodu. Ale najbardziej dziwi mnie to, że w ogóle mogłem napisać odpowiedź, szczególnie biorąc pod uwagę, że Brain-Flak jest

Minimalistyczny esolang zaprojektowany z myślą o bolesnym użytkowaniu

Później spróbuję zagrać w golfa, ale i tak chciałem to zrobić.

Mam szczegółowe wyjaśnienie, ale ma około 6 tysięcy znaków, więc myślę, że nie byłoby rozsądnie wklejać całej tej odpowiedzi. Możesz to przeczytać tutaj jeśli chcesz. Dodam tutaj krótsze wyjaśnienie.

Podstawową ideą jest to, że powtarzamy następujące kroki dla każdej postaci na stosie:

  • Sprawdzamy każdą postać, aby sprawdzić, czy pasuje do nawiasu. Jeśli jest to nawias otwierający, wypychamy liczbę na drugi stos zgodnie z następującym odwzorowaniem:

    ( = 1
    < = 2
    [ = 3
    { = 4
    
  • Następnie sprawdzamy, czy pasuje do jakiegokolwiek zamka zamykającego. Jeśli tak jest, wypychamy równoważną liczbę na alternatywny stos, tak jak w przypadku otwierania nawiasów. Następnie sprawdzamy, czy dwie górne liczby są równe. Jeśli tak, oba zostaną wyświetlone, a program będzie działał normalnie. Jeśli nie są, usuwamy oba stosy (aby zatrzymać zapętlenie) i pchamy jeden na alternatywny stos. Jest to zasadniczo stwierdzenie „break”.

  • Po sprawdzeniu 8 typów nawiasów, przepychamy wartość tego przebiegu przez pętlę. Ponieważ zerujemy większość z nich, jedynymi fragmentami, które mają dowolną wartość, są warunki warunkowe, gdy porównujemy je z nawiasami. Więc jeśli dowolny nawias jest dopasowany, cała pętla ma wartość 1. Jeśli żadna z nich nie ma, cała pętla ma wartość 0. W tym przypadku wyczyścimy oba stosy i wypchniemy 0 na alternatywny stos. Znowu jest to jak stwierdzenie „break”.

Po uruchomieniu tej głównej pętli reszta jest dość prosta. Znajdujemy się na (pustym) głównym stosie, a alternatywny stos jest pusty (jeśli pasowały nawiasy klamrowe) lub niepusty, jeśli nie były. Więc uruchamiamy to:

#Toggle to the alternate stack
<>

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

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

Spowoduje to wypchnięcie 0 lub 1 na główny stos, a kiedy program się zakończy, zostanie domyślnie wydrukowany.



poprawki

  • Usunięto nadmiarowość push pop

  • Zmieniono moją logikę licznika zerowego


1
Awwwwwweeeeesommmmeeeee!
Arjun

23

Brain-Flak , 204 196 190 bajtów

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

Wypróbuj online!

-8 bajtów dzięki Wheat Wizard. -6 bajtów dzięki Jo King.

Wyjaśnienie

Ten program przechowuje kody znaków wszystkich bieżących niezamkniętych nawiasów na drugim stosie. Pary wsporników <>, []i {}każdy ma kody znaków, które różnią się od dokładnie 2, więc nie ma potrzeby, by sprawdzić dla nich konkretnie. Para ()różni się tylko o 1, więc sprawdzamy (konkretnie i skutecznie zmniejszamy ten bajt (faktycznie zwiększamy co drugi bajt) przed kontynuowaniem.

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

„logiczny brak różnicy” (znany również jako równy) może być krótszy, ponieważ([{}]<>({}))((){[()](<{}>)}{})
Wheat Wizard

Myślę, że możesz zastąpić ten ostatni czek ({<>[()]}())dla -6 bajtów
Jo King

@JoKing Thanks. Nie sądzę, bym kiedykolwiek to zauważył.
Nitrodon

Tak, wymyśliłem to we własnej odpowiedzi i zdałem sobie sprawę, że dotyczy to również twojego
Jo King

13

JavaScript (ES6), 52 50 bajtów

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

Wielokrotnie usuwaj nawiasy, aż wynik będzie taki sam jak oryginał, a następnie zwracaj wartość false, chyba że łańcuch jest teraz pusty.

Edycja: Zapisano 2 bajty dzięki @ edc65.



11

CJam, 25 24 23 21 bajtów

Dzięki Sp3000 za oszczędność 2 bajtów.
Dzięki jimmy23013 za oszczędność 2 bajtów.

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

Zestaw testowy.

Działa zasadniczo taka sama jak innych odpowiedzi: my wielokrotnie usunąć (), [], <>a {}z łańcucha i sprawdzić, czy możemy skończyć z pustym ciągiem. Aby uniknąć konieczności sprawdzania, kiedy skończymy, usuwamy pary Nrazy gdzieN jest długość ciągu, co zawsze jest wystarczające (ponieważ każda iteracja usunie co najmniej dwa znaki, chyba że skończymy). Cieszę się, że to nie bije Retiny. :) (Chociaż Pyth lub Jelly mogą ...)

Jest jedna fajna sztuczka golfowa: aby uzyskać ciąg ()<>[]{}, używamy:

{()<>}a`$

, {()<>}To tylko blok (tj. Funkcja), który zawiera inne nawiasy jako kod. Z azawijamy blok do tablicy. Ciąg `znaków określa tę tablicę, co daje "[{()<>}]". Na koniec sortujemy ciąg za pomocą$ , co przestawia nawiasy ()<>[]{}.


Nie znam twojego języka, ale twój opis sztuczki golfowej sprawia, że ​​brzmi tak ()<>[]{}`, jakby działał równie dobrze i miałby taką samą liczbę bajtów, prawda?
Kaczka Mooing

1
@MooingDuck Nie, ponieważ ()<>są cztery operatory (zmniejszanie, zwiększanie, a następnie porównywanie lub obcinanie w zależności od operandów), które byłyby wykonywane natychmiast, podczas gdy {}oznacza blok (odpowiednik funkcji CJam), tj. Fragment kodu, który został właśnie wciśnięty na stos bez natychmiastowej oceny. Dlatego muszę {}owinąć ()i <>, ale potem użycie ado umieszczenia wszystkiego w tablicy jest krótsze niż [...].
Martin Ender,

10

Python, 67 bajtów

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

Generuje i analizuje wyrażenie, które wygląda

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

i sprawdza, czy wynik jest pusty.

Sp3000 zaoszczędził 8 bajtów, wskazując, że [],(),{}można je wpisać bez cudzysłowów, ponieważ są to obiekty Pythona, a dwa pareny były niepotrzebne.


8

Yacc, 119 bajtów

Nie używa wyrażeń regularnych / zamień.

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

Nie golfił

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

Kompilacja

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

Stosowanie

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

7

Pyth, 31 25 24 bajtów

Gra w golfa do 25 bajtów dzięki FryAmTheEggMan Usunięto 1 bajt

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

Wypróbuj tutaj: pakiet testowy !

Nadal jestem nowicjuszem w Pythonie, każda pomoc jest mile widziana.

Wyjaśnienie

VQ                         For N in range(0, len(z)), with Q being the evaluated input.
                           Optimal solution would be to use range(0, len(z)/2) instead, but it add two bytes.
  =:Q"<>|\[]|{}|\(\)"k     assign Q without {}, [], <> nor () (regex replacement) to Q
                      ;    End of For loop
                       !   Logical NOT of Q's length (Q is the input, but has gone several times through y, and Q is implicit).
                           This last operation returns True if len(Q) is 0 (which means all brackets were matched), False otherwise

BTW, gratulacje dla drugiej odpowiedzi Pyth (która obecnie wynosi 20 bajtów)


Witamy w Programowaniu zagadek i Code Golf!
Adnan

@Adnan Dziękujemy! To jest mój pierwszy golf!
FliiFe,

Miły pierwszy golf! Z pewnym przegrupowanie i rzeczy, można uzyskać do 25: Vz=:z"<>|\[]|{}|\(\)"k;!z. Zwłaszcza, że ​​w zasadzie nigdy nie musisz używać, ljeśli tak naprawdę nie potrzebujesz liczby, i =automatycznie zgaduje pierwszą zmienną użytą w wyrażeniu. Daj mi znać, jeśli chcesz, abym wyjaśnił coś jeszcze w czacie Pyth :)
FryAmTheEggman

@FryAmTheEggman Thanks! Nie wiedziałem l, że to niepotrzebne, dobrze wiedzieć. Na początku zadeklarowałem funkcję, ponieważ moja logika była inna i zapomniałem ją usunąć. Czy mam dołączyć odpowiedź do mojej? (Jestem nowicjuszem>. <)
FliiFe

3
Ogólnie rzecz biorąc, jeśli jest opublikowany w komentarzu, autor komentarza chce, abyś go używał. Więc śmiało! :)
FryAmTheEggman

6

Pyth, 20 bajtów

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

Wypróbuj online: pakiet testowy

Wielokrotnie usuwa wystąpienia [], (), <>i {}poprzez rozdzielenie i ponownego łączenia. Sprawdza, czy wynikowy ciąg jest pusty, czy nie.


4

JavaScript ES6, 54 bajty

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

Używa rekursywnej implementacji zastępowania. Wystarczająco proste.



4

Perl, 34 33 bajtów

Obejmuje +2 za -lp

Uruchom z wejściem na STDIN:

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

brackets.pl:

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

Znajduje pierwszą parę wsporników bez niczego między nimi i usuwa ją, o ile istnieje. Następnie sprawdza, czy końcowy ciąg jest pusty.


Nie s/\(\)|\[]|<>|{}//&&redo;$_=!$_działałoby? :)
Dada

Byłoby wspaniale, gdybyś mógł podać wyjaśnienie.
Prashant Pokhriyal

@Dada Oczywiście. Muszę się
starzeć

4

Brain-Flak , 204 bajty

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

Wypróbuj online!

Nie tak krótki jak odpowiedź Nitrodena , ale stosuje zupełnie inne podejście. Ten wielokrotnie przechodzi przez wejście, usuwając sąsiednie pasujące pary nawiasów za każdym razem, dopóki ich nie ma. W tym momencie, jeśli na stosie pozostało coś, łańcuch nie został w pełni dopasowany.

Wyjaśnienie:

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

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

Sformatowany:

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

Oczekuje wprowadzania bez końcowego znaku nowej linii. Drukuje \x00jako fałszywe i \x01prawdziwe.

Wypróbuj online.

Podejście: utrzymuj stos zaczynając od \x01, i popchnij odpowiedni wspornik zamykający, ilekroć napotkasz wspornik otwierający. Przed sprawdzeniem, czy bieżący znak jest nawiasem otwierającym, najpierw sprawdź, czy jest równy nawiasowi zamykającemu na górze stosu, a jeśli tak, to go pop. Jeśli nie jest to właściwy nawias zamykający ani nawias otwierający, wykorzystaj resztę danych wejściowych, przesuwając wskaźnik w prawo. Na koniec sprawdź, czy wskaźnik znajduje się obok początkowego \x01.


2

Grime v0.1, 34 bajty

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

Drukuje 1dla dopasowania i 0bez dopasowania. Wypróbuj online!

Wyjaśnienie

Grime to mój język dopasowywania wzorów 2D zaprojektowany do tego wyzwania ; może być również użyty do dopasowania ciągów 1D. To moja pierwsza odpowiedź. Zmodyfikowałem Grime dzisiaj, ale tylko po to, aby zmienić charakter jednego elementu składni ( `zamiast ,), więc nie wpływa to na mój wynik.

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 bajtów, niekonkurujące

Wypróbuj tutaj!

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/

Jest trochę więcej golfa do zrobienia, ale przynajmniej działa. Dodałem polecenie ðśledzenia stosów po tym wyzwaniu, aby było to zdalnie możliwe / łatwe. Wyjaśnię to trochę, ale generalnie śledzi wszystkie ciągi iterowane i szuka powtórzeń; jeśli jest powtórzenie, to ciąg jest nieredukowalny. W przeciwnym razie łańcuch zostanie zredukowany do pustego łańcucha / stosu i zostanie wygenerowany 1. W przeciwnym razie dane wyjściowe nie zostaną wygenerowane.


2

PowerShell v2 +, 63 62 bajty

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

Nie mogę do końca złapać JavaScript, ale obecnie wypiera inne nie-esolangi.

Podobne podejście jak inne odpowiedzi: prosty pętla, która trwa tak długo, jak możemy usunąć jedną [], ()lub <>(z kilku zewnętrznych znaków, ponieważ musimy uciec regex specjalności). Używamy $bjako pomocnika po drodze, aby pamiętać, jak $austawione były nasze poprzednie pętle . Niezainicjowana zmienna jest $nullwięc, więc przy pierwszym napotkaniu pętli, $aoczywiście nie jest równa$null .

Pod koniec pętli, $ajest albo pusta, czy nie, a nie-logiczna tego łańcucha jest albo TruealboFalse .

Przykład

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 bajtów

Ogolono 8 bajtów dzięki @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);}

Używa stosu.


Lubie c%7&2. W rzeczywistości nie potrzebujesz k. Zamiast tego możesz po prostu inkrementować, igdzie chcesz zmodyfikować, kponieważ i tak musisz sprawdzić, czy iostatecznie wynosi zero. Coś jak ten (kod nietestowanego) 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 - Czy zwiększanie będzie działać? Musimy także unikać subskrybowania tablicy z wartością ujemną, więc musimy przetestować i lub k dla for.
mIllIbyte

O, rozumiem. Nadal jest jednak miejsce na ulepszenia: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 6.04.16

@xsot - Dziękujemy! Podsumowując oszczędności, przeczytaj zapisane 5 bajtów, ^ zapisany jeden i środkowy operand operatora warunkowego zapisany 2. Jestem zaskoczony, że środkowy operand operatora warunkowego może być przypisaniem. Myślałem, że wystąpi błąd, na przykład „brak: przed =”.
mIllIbyte

@xsot - próbowałem zwiększać i zamiast używać k, jak zasugerowałeś wcześniej: 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);}Ale to jeszcze nie działa jak na dane wejściowe ())), ponieważ „wyskakiwanie” ze stosu tak naprawdę nie zeruje wartości w tablicy.
mIllIbyte

2

Java 7, 156 151 bajtów

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

Nie oczekuję, że wygra to, ale nie widziałem jeszcze odpowiedzi w Javie. Ponadto lubię czaić się przy PPCG i cieszę się, że mogę głosować / komentować inne odpowiedzi.

Dane wejściowe są podawane jako parametry programu. Jest to zgodne z tym samym formatem, co wiele innych odpowiedzi tutaj, ponieważ wykonuje w pętli zamianę wyrażenia regularnego. Pierwotnie miałem pętlę N razy, gdzie N jest długością oryginalnego łańcucha, ale pętla do Integer.MAX_VALUEjest krótsza:]. Powinno to być w porządku, ponieważ Integer.MAX_VALUEjest to maksymalna długość StringJavy, więc domyślnie zakłada się, że długość danych wejściowych jest czymś, co może obsłużyć Java. Środowisko wykonawcze jest dość złe (zajęło około 20 minut na moim lappytopie) z powodu pętli, ale nie widziałem żadnych ograniczeń.


2

Haskell , 151 bajtów

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

Wypróbuj online!


Kilka rzeczy: Ponieważ funkcja (#)musi być wywołana z pustym łańcuchem jako drugim argumentem, musisz liczyć się do liczby (#"")bajtów. Również tylko Truei Falsesą uważane za prawdziwe / fałszywe, patrz Przewodnik po zasadach gry w golfa .
Laikoni,

1
Jednak cztery wiersze z nawiasami zamykającymi można zastąpić a:x#b:y|a==b=x#y, zmniejszając liczbę bajtów do 113: Wypróbuj online!
Laikoni,

2
109 bajtów: Wypróbuj online!
Laikoni


1

Python 2, 80 bajtów

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

1

Julia, 51 bajtów

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

Najmniej szalony z kilku opcji. Jak można się było spodziewać, wykorzystanie siły wyrażenia regularnego jest najkrótszą ścieżką do dopasowania łańcucha, ale tak naprawdę ma to zastosowanie tylko wtedy, gdy wzorzec dopasowania jest regularny. Próba wykonania wzorców rekurencyjnych PCRE kończy się powiększaniem rozmiaru kodu, albo przez sprawdzenie, czy cały ciąg jest zgodny, albo przez zakotwiczenie końców, a następnie utworzenie konstrukcji określającej ciało wewnętrzne dla rekursji wyrażenia regularnego. Żaden z nich nie jest ładny ani nie sprzyja kodowaniu w golfa.

Wyjaśnienie:

~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

Funkcja wielokrotnie usuwa sąsiednie pary nawiasów z jedynego argumentu i zwraca wartość true, jeśli może w ten sposób uzyskać pusty ciąg.


1

sed, 39 36 bajtów (34 dla kodu, 2 dla -r)

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

Wypróbuj online!

sed wersja tego, co wydaje się być standardowym podejściem. Wymaga rozszerzonych wyrażeń regularnych ( sed -r)

Oszczędność 3 bajtów dzięki szarlatanowi Krowy


Możesz usunąć ais :ai tazaoszczędzić bajty
Kritixi Lithos

@KritixiLithos Najwyraźniej był to błąd w GNU sed, który został usunięty w 4.3 . Prawdopodobnie upuściłbym te postacie, gdyby ten wpis był wystarczająco blisko lidera, aby miał szansę wygrać, ale ponieważ tak nie jest, zostawię go w bardziej przenośnej formie, aby nie przestał działać wraz ze wzrostem liczby systemów do 4.3.
Ray

1
Patrząc wstecz na to, jestem pewien, że możesz też upuścić qz nich /./i upuścić szelki. Wypróbuj online! Wynika to z tego, jak cdziała
hange

@Cowsquack Thanks. Edytowane.
Ray

0

05AB1E, 9 bajtów

žu2ôõ:g2Q

Dane wejściowe podano w cudzysłowie.

Wypróbuj online!

Wyjaśnienie:

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

Dłużej niż odpowiedzi C i 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)

Nie używa wyrażenia regularnego, zamiast tego używa pierwszego znaku, aby określić, co jest znacznikiem zamykającym, i znajduje pierwszy indeks, w którym nawias jest zrównoważony (skumulowana suma wynosi zero). Następnie iteracyjnie sprawdza, czy zawartość w nawiasach i po nawiasach jest poprawna.

Muszę sprawdzić, czy istnieje lepsze podejście ...


0

Lua , 295 bajtów

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

Wersja bez golfa

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

Wypróbuj 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}

Podejście polega na przekonwertowaniu sekwencji na kod R, a następnie próbie jej przeanalizowania i oceny. Jeśli to daje błąd, wróć FALSE.

Ale jest mały problem ... Reguły R dla nawiasów są różne, więc <i> nie są wsporniki w ogóle, a inne typy mają swoje własne zasady. Rozwiązuje to rewolucyjne podejście - funkcja piszcząca, której jedyną funkcją jest sygnalizowanie błędu, jeśli głowa i ogon piszczą na różne sposoby.

Na przykład []przekształca się w S('[', {}, ']'), gdzie S jest zdefiniowane jako ...

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

Ponieważ pisk głowy i pisk ogona pasują do siebie, żaden błąd nie jest zgłaszany.

Kilka innych przykładów (lewa część jest sekwencją nawiasów, a prawa część to jej przekształcenie w prawidłowy kod R, który można ocenić):

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

Niektóre inne sekwencje nawiasów powodują błędy analizy:

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

Więc pozostała część po prostu łapie błędy i zwraca FAŁSZ, jeśli są, i PRAWDA, jeśli nie ma.

Kod czytelny dla człowieka:

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

Zastosowanie na przykładowych przypadkach:

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 
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.