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:
Każda postać to nawias,
Każda para wsporników ma prawidłowy wspornik otwierania i zamykania we właściwej kolejności, oraz
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.
źródło
[}
pasuje? A jeśli nie, to gdzie jest wykluczone przez te zasady?Each pair of brackets has the correct opening and closing bracket and in the right order.
Odpowiedzi:
05AB1E , 19 bajtów
Dane wejściowe podano w cudzysłowie . Kod:
Bzdury, znaleziono wiele błędów i niezaimplementowanych funkcji. Wyjaśnienie:
To właściwie trudna część. Tak to wygląda w pseudokodzie:
Jest to objęte niniejszą częścią kodu 05AB1E :
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:
Wykorzystuje kodowanie CP-1252 . Wypróbuj online! (nieznacznie zmodyfikowany, ponieważ powyższa wersja jest nieaktualna).
źródło
õ
było wcześniej dodane?Brain-Flak ,
1101, 1085, 981 bajtówWypróbuj online!
Jest to 980 bajtów kodu źródłowego i
+1
dla-a
flagi 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.
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
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:
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:
Spowoduje to wypchnięcie 0 lub 1 na główny stos, a kiedy program się zakończy, zostanie domyślnie wydrukowany.
Dzięki @WheatWizard za wymyślenie dobrego fragmentu „równego” i „logicznego nie” oraz za regularne aktualizowanie wiki github przydatnymi przykładami.
Dzięki @ ASCII-tylko za napisanie internetowego metagolfera liczb całkowitych, który ogromnie pomógł w napisaniu tego programu
poprawki
Usunięto nadmiarowość push pop
Zmieniono moją logikę licznika zerowego
źródło
Brain-Flak ,
204196190 bajtówWypró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.źródło
([{}]<>({}))((){[()](<{}>)}{})
({<>[()]}())
dla -6 bajtówJavaScript (ES6),
5250 bajtówWielokrotnie 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.
źródło
Siatkówka, 20 bajtów
Wypróbuj online
źródło
CJam,
25242321 bajtówDzięki Sp3000 za oszczędność 2 bajtów.
Dzięki jimmy23013 za oszczędność 2 bajtów.
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 paryN
razy 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:,
{()<>}
To tylko blok (tj. Funkcja), który zawiera inne nawiasy jako kod. Za
zawijamy blok do tablicy. Ciąg`
znaków określa tę tablicę, co daje"[{()<>}]"
. Na koniec sortujemy ciąg za pomocą$
, co przestawia nawiasy()<>[]{}
.źródło
()<>[]{}`
, jakby działał równie dobrze i miałby taką samą liczbę bajtów, prawda?()<>
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życiea
do umieszczenia wszystkiego w tablicy jest krótsze niż[...]
.Python, 67 bajtów
Generuje i analizuje wyrażenie, które wygląda
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.źródło
Yacc, 119 bajtów
Nie używa wyrażeń regularnych / zamień.
Nie golfił
Kompilacja
Stosowanie
źródło
Pyth,
312524 bajtówGra w golfa do 25 bajtów dzięki FryAmTheEggMan Usunięto 1 bajt
Wypróbuj tutaj: pakiet testowy !
Nadal jestem nowicjuszem w Pythonie, każda pomoc jest mile widziana.
Wyjaśnienie
BTW, gratulacje dla drugiej odpowiedzi Pyth (która obecnie wynosi 20 bajtów)
źródło
Vz=:z"<>|\[]|{}|\(\)"k;!z
. Zwłaszcza, że w zasadzie nigdy nie musisz używać,l
jeś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 :)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>. <)Pyth, 20 bajtów
Wypróbuj online: pakiet testowy
Wielokrotnie usuwa wystąpienia
[]
,()
,<>
i{}
poprzez rozdzielenie i ponownego łączenia. Sprawdza, czy wynikowy ciąg jest pusty, czy nie.źródło
JavaScript ES6, 54 bajty
Używa rekursywnej implementacji zastępowania. Wystarczająco proste.
źródło
Regex (smak PCRE),
4137 bajtówTylko standardowe rozwiązanie z rekursywnym wyrażeniem regularnym.
Dzięki jimmy23013 za zgolenie 4 bajtów
źródło
Perl,
3433 bajtówObejmuje +2 za
-lp
Uruchom z wejściem na STDIN:
brackets.pl
: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.
źródło
s/\(\)|\[]|<>|{}//&&redo;$_=!$_
działałoby? :)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:
źródło
Brainfuck, 132 bajty
Sformatowany:
Oczekuje wprowadzania bez końcowego znaku nowej linii. Drukuje
\x00
jako fałszywe i\x01
prawdziwe.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
.źródło
Grime v0.1, 34 bajty
Drukuje
1
dla dopasowania i0
bez 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.źródło
Reng v.3.3, 137 bajtów, niekonkurujące
Wypróbuj tutaj!
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 wygenerowany1
. W przeciwnym razie dane wyjściowe nie zostaną wygenerowane.źródło
PowerShell v2 +,
6362 bajtyNie 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$b
jako pomocnika po drodze, aby pamiętać, jak$a
ustawione były nasze poprzednie pętle . Niezainicjowana zmienna jest$null
więc, więc przy pierwszym napotkaniu pętli,$a
oczywiście nie jest równa$null
.Pod koniec pętli,
$a
jest albo pusta, czy nie, a nie-logiczna tego łańcucha jest alboTrue
alboFalse
.Przykład
źródło
C,
121122114 bajtówOgolono 8 bajtów dzięki @xsot!
Używa stosu.
źródło
c%7&2
. W rzeczywistości nie potrzebujeszk
. Zamiast tego możesz po prostu inkrementować,i
gdzie chcesz zmodyfikować,k
ponieważ i tak musisz sprawdzić, czyi
ostatecznie 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);}
.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);}
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.Java 7,
156151 bajtówNie 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_VALUE
jest krótsza:]. Powinno to być w porządku, ponieważInteger.MAX_VALUE
jest to maksymalna długośćString
Javy, 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ń.źródło
Haskell , 151 bajtów
Wypróbuj online!
źródło
(#)
musi być wywołana z pustym łańcuchem jako drugim argumentem, musisz liczyć się do liczby(#"")
bajtów. Również tylkoTrue
iFalse
są uważane za prawdziwe / fałszywe, patrz Przewodnik po zasadach gry w golfa .a:x#b:y|a==b=x#y
, zmniejszając liczbę bajtów do 113: Wypróbuj online!Python 2.7, 96 bajtów
źródło
Python 2, 80 bajtów
źródło
Julia, 51 bajtów
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:
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.
źródło
sed,
3936 bajtów (34 dla kodu, 2 dla -r)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
źródło
a
is:a
ita
zaoszczędzić bajtyq
z nich/./
i upuścić szelki. Wypróbuj online! Wynika to z tego, jakc
działa05AB1E, 9 bajtów
Dane wejściowe podano w cudzysłowie.
Wypróbuj online!
Wyjaśnienie:
źródło
Clojure, 153 bajty
Dłużej niż odpowiedzi C i Brainfuck: o
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 ...
źródło
Lua , 295 bajtów
Wersja bez golfa
Wypróbuj online!
źródło
Japt v2.0a0
-!
, 16 bajtówSpróbuj
źródło
R 298
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ę wS('[', {}, ']')
, gdzie S jest zdefiniowane jako ...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ć):
Niektóre inne sekwencje nawiasów powodują błędy analizy:
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:
Zastosowanie na przykładowych przypadkach:
źródło