Kolejny problem z analizowaniem Brainfuck, ale tym razem ... inaczej.
Pracujesz w Infinite Monkeys Incorporated, firmie produkującej programy Brainfuck, w celu rozwiązania różnych interesujących problemów (przypadkowo, nie mniej - przecież firma tworzy programy losowe). Wydaje się jednak, że twoje szybkie maszyny Turinga, które wykonują tylko Brainfuck, mają mały i kosztowny problem z błędami składniowymi - zrób je, a komputer wybuchnie. Prawdopodobnie jest to wada projektowa, ale nikt nie zadał sobie trudu, aby dowiedzieć się, dlaczego tak się dzieje.
Ponieważ maszyny Turinga (szczególnie szybkie) są drogie (w końcu mają nieskończoną pamięć RAM, która kosztuje), lepiej upewnić się, że program nie ma żadnych błędów składniowych przed wykonaniem kodu. Twoja firma uruchomi dużo kodu, więc ręczna weryfikacja nie będzie działać. Napisz program, który odczytuje STDIN dla kodu Brainfuck i kończy pracę ze statusem wyjścia ustawionym na wartość inną niż 0 (błąd), jeśli program ma jakiś błąd składniowy (na przykład
]
jest błędem składniowym, ponieważ nie ma pasującego dopasowania[
). Wyjdź ze statusem wyjścia ustawionym na 0, jeśli program działa poprawnie.Upewnij się, że Twój program poprawnie zauważa błędy dotyczące
[]
. Nie chciałbyś, żeby inny komputer wybuchł, prawda? Aha, i upewnij się, że jest tak krótki, jak to możliwe - twój szef płaci za krótkie programy (ponieważ uważa, że są one szybkie lub coś w tym rodzaju). Aha, i nie musisz kodować w Brainfuck (w rzeczywistości nie możesz, ponieważ Brainfuck nie obsługuje kodów wyjścia) - twój kod zostanie uruchomiony na normalnym komputerze.
Jak widać, Twoim zadaniem jest sprawdzenie, czy program Brainfuck jest „prawidłowy” (ma sparowane []
symbole). Pamiętaj, że programy Brainfuck mogą mieć inne znaki niż []
, więc nie odrzucaj programu tylko dlatego, że ma inne polecenia. Najmniejszy kod wygrywa, ale prawdopodobnie i tak bardziej zależy Ci na upvotes.
źródło
GCD(a,b)
zamiast0 != a || b
.Odpowiedzi:
GolfScript, 18 znaków
Ten kod działa poprawnie z kodem wyjścia 0 (i drukuje śmieci na standardowe wyjście), jeśli nawiasy kwadratowe na wejściu są zrównoważone. Jeśli nie są, nie działa z niezerowym kodem wyjścia i wyświetla komunikat o błędzie na stderr, np .:
lub
Ponieważ wyzwanie nie mówiło nic o wyjściu do stdout / stderr, sądzę, że to kwalifikuje się. W każdym razie możesz zawsze przekierować je do
/dev/null
.Wyjaśnienie:
Kod
{[]`?)},
usuwa z danych wszystko oprócz nawiasów kwadratowych i~
ocenia wynik jako kod GolfScript. Problem polega na tym, że niezbalansowane nawiasy klamrowe są całkowicie legalne w GolfScript (a tak naprawdę mój kod zawiera jeden!), Więc potrzebujemy innego sposobu, aby spowodować awarię kodu.Sztuką, której używam, jest pozostawienie kopii danych wejściowych na dole stosu, zebranie całego stosu do tablicy (używając niezrównoważonego
]
) i przesunięcie pierwszego elementu. W tym momencie mogą się zdarzyć trzy rzeczy:[
, próba przesunięcia elementu poza pustą tablicę spowoduje awarię interpretera (co w tym przypadku jest dokładnie tym, czego chcemy!)]
lub niezamknięte[
) będzie to tablica.Mój oryginalny 14-znakowy wpis porównał następnie przesuniętą wartość z łańcuchem, który zawiesiłby się, gdyby była zagnieżdżoną tablicą. Niestety okazuje się, że porównując mieszkanie (lub, w szczególności, pustej) tablicy z łańcuchem jest również dozwolone w GolfScript, więc musiałem zmienić tack.
Zamiast tego moje bieżące zgłoszenie wykorzystuje metodę bardzo brutalnej siły, aby odróżnić tablice od łańcuchów: odkrywa je i próbuje znaleźć pierwsze wystąpienie
[
(kod ASCII 91), które będzie zerowe, jeśli tylko nieewaluowane zmienna była tablicą. Jeśli tak, podzielenie zera samym sobą powoduje pożądaną awarię.Ps. Dwa inne 18-znakowe rozwiązania to:
i
Niestety, nie znalazłem jeszcze krótszego sposobu rozwiązania „problemu pustej tablicy”.
źródło
][
(tzn. czy zawodzi w twoim programie?)[[]
; Naprawiłem to teraz, kosztem 4 znaków, i teraz przechodzi wszystkie moje testy.1+
zamieni pustą tablicę w niepustą tablicę, niepustą tablicę w niepustą tablicę, a łańcuch w łańcuch..{[]`?)},~](n<
. Próbowałem twojego1+
, ale wygląda na to, że tablica musi zawierać coś innego niż liczbę (przypuszczalnie tak, że interpreter się zawiesi, gdy spróbuje rekurencyjnie porównać znak z tablicą / łańcuchem). Użycien+
również nie działa, ponieważ wymusza tablicę na ciąg;[n]+
ma pracę, ale nadal stawia mnie na 18 znaków.Brainfuck 76 bajtów
To wychodzi z więzów, jeśli nawiasy kwadratowe są niezrównoważone, co powoduje, że interpreter / kompilator bf nie działa w czasie wykonywania, a niektóre z nich mają kody wyjścia, które to odzwierciedlają.
wymaga eof = 0, zawijania wartości i skończonej liczby komórek
W Ubuntu możesz użyć interpretera
bf
(sudo apt-get install bf
)źródło
Brainfuck
jest zakończony Turinga bez I / O, ponieważ można uruchomić program, który oblicza dowolne obliczenia i zobaczyć wynik, sprawdzając jego pamięć po uruchomieniu. BF bez I / O sprawiłoby, że ludzie byliby mniej zainteresowani, ponieważ trudno byłoby tworzyć narzędzia. np. nigdy nie mogłem zrobić mojego tłumacza seplenienia .Befunge 98 -
26312019 znakówPozbyłem się ogromnych warunków. Teraz program działa w następujący sposób:
q
zamyka program i wyświetla najwyższą wartość jako wartość błędu. Wartość błędu wyniesie-11, jeśli jest ich zbyt wiele]
, 0, jeśli są zrównoważone, idodatniaujemna, jeśli jest ich zbyt wiele[
. Jeśli liczba jestdodatniaujemna, totyleabsolutnej wartości tej liczby]
jest potrzebnych do zrównoważenia programu.Edycja: Przełączany przyrost i spadek.
[
służy do zwiększania licznika i]
służy do zmniejszania go. Przełączając go, zapisuję 1 znak, ponieważ dla warunku wyjścia muszę tylko sprawdzić, czy licznik jest dodatni, a nie ujemny.Stara wersja
Ten kod działa w następujący sposób:
Edycja: zdałem sobie sprawę, że to zaakceptowane dane wejściowe, takie jak
][
, teraz kończy się, gdy liczba staje się ujemna, używającźródło
[
i]
aby porównać z obu.J (
3835)Wyjaśnienie:
1!:1[3
: przeczytaj standardowe'[]'=/
: utwórz macierz, w której pierwszy wiersz jest maską bitową[
s na wejściu, a drugi wiersz to]
s.1 _1*
: pomnóż pierwszy rząd przez 1, a drugi rząd przez -1.+/
: zsumuj kolumny macierzy razem, podając wcięcie delta na znak+/\
: utwórz ich bieżącą sumę, podając poziom wcięcia dla każdej postaci({:+.<./)
: zwraca GCD ostatniego elementu ({:
) i najmniejszego elementu (<./
). Jeśli wszystkie nawiasy klamrowe pasują do siebie, oba powinny być,0
więc to zwróci0
. Jeśli nawiasy klamrowe nie pasują, zwróci niezerową wartość.exit
: ustaw na tym wartość wyjścia i wyjdź.źródło
rubin (64)
poprzednio (68) było to:
Używa innego równoważnego rozwiązania
nie można używać w
size
pojedynkę, ponieważ dałoby to fałszywe negatywy (!!!), gdy całkowita liczba niewyważonych nawiasów jest wielokrotnością 256źródło
=
operatora.0
mogą pójść.Perl, 30 znaków
Twoje podstawowe rekurencyjne wyrażenie Perla na ratunek:
Dla osób niezaznajomionych z używanymi tutaj argumentami wiersza poleceń:
-0
pozwala ustawić znak końca wiersza na potrzeby wprowadzania plików; użycie-0
bez argumentu ustawia znak końca linii na EOF.-n
automatycznie odczytuje wcześniej dane wejściowe (w tym przypadku cały plik)$_
.Jeśli wyrażenie regularne pasuje, zwraca wartość true, która jest negowana do 0 dla kodu wyjścia. W przeciwnym razie fałszywa wartość zwracana daje kod wyjścia 1.
źródło
bash (tr + sed) - 42
Jeśli nie przeszkadza ci komunikat o błędzie, możesz usunąć ostatnią spację między
`
i,]
aby uzyskać długość 41.źródło
cat
i$()
("[]"
można również zapisać jako[]
). Zaakceptowałem tę odpowiedź, ale dopóki nie zobaczę poprawy długości, nie zamierzam jej głosować, ponieważ choć jest krótka, może być o wiele krótsza dla bash.$()
z backticks i zrobił to"[]"
->[]
pan sugeruje.Perl (56 znaków)
Oczywiste rozwiązanie Perla: rekursywne wyrażenie regularne. Niestety jest to dość rozbudowana konstrukcja.
źródło
Haskell (143)
do jgon: Używanie 2 strażników wydaje się być bardziej gęste niż jeśli-to-inaczej. Poza tym nie sądzę, żeby sprawdził, czy nawiasy są w odpowiedniej kolejności („] [” przechodzi)
źródło
C,
7364 znakówDzięki sugestiom z breadboksa (choć to prawdopodobnie wymaga little-endian do pracy):
Jak to działa:
i
jest inicjowana na 0c
staje się domyślną int, która dostajeargc
(inicjowana na 1, ale nie obchodzi nas to, o ile wyższe bity nie są ustawione)read(0,&c,1)
wczytuje pojedynczy znak do niskiego bajtu c (w architekturze little-endian) i zwraca 0 w EOF;i+1 != 0
chyba że cytat w zbilansowanym nawiasie wynosi -1; pomnożenie ich razem działa jako (bezpieczna) wartość logiczna ORAZ, która zajmuje jeden mniej znaków niż&&
c==91
ocenia na 1 dla'['
, ic==93
ocenia na 1 dla']'
. (Może być trochę sztuczek, które byłyby mniejsze, ale nic nie mogę wymyślić.)return i
wychodzi z kodem stanu 0, jeśli jest zrównoważony, niezerowy, jeśli nie jest. Zwracanie -1 technicznie narusza POSIX, ale nikt tak naprawdę nie dba o to.Poprzednia wersja:
źródło
getchar()
zamiast odczytu skróci kod i pozwoli na użycie (niejawne)int
zamiastchar
zmiennej. Pamiętaj również, że globały są automatycznie inicjowane na zero.c;
definiuje globalny int.][
? Jestem pewien, że nie jest zrównoważony. Czy nie musisz śledzić, czy co najmniej raz jest ujemny?Lua, 56 lat
źródło
"^%b[]$"
co to jest? Możesz wytłumaczyć? Z pewnością to nie jest wyrażenie regularne?^
), zbalansowany zestaw[
iz]
dowolną inbetween (%b[]
) i koniec string ($
).GTB , 55
Brakuje
[]
Użyj,
0
aby zatrzymać.źródło
MATHEMATICA, 88 znaków
źródło
s name like
RegularExpression` iStringLength
nigdy nie mogę wygrać tekstowego golfa w kontekście matematyki! :)ToCharacterCode
jest znacznie dłuższy niżord
... PS: A co z ustawieniem kodu wyjścia?Length[StringCases[s,"["|"]"]//.{x___,"[","]",y___}:>{x,y}]
Rubin,
5958Skanuje nawias otwierający i zamykający, licząc
[
jako 1 i]
jako -1, i kończy działanie, jeśli liczba spadnie poniżej 0.źródło
exit 1
na wypadek, gdybyś poprosił).Wapń , 104 bajty
Pełny rozwinięty (notatka nie działa w tłumaczu online, ponieważ input () jest wyłączony) tutaj
źródło
Kod maszynowy Turinga,
286276 bajtówPonownie używam zdefiniowanej tutaj składni tabeli reguł .
Kończy się w stanie,
halt
aby zaakceptować ihalt-err
odrzucić dane wejściowe .źródło
halt-err
może być krótszy,halt*
na przykład na przykład.Pyth, 25 bajtów
Wypróbuj online!
Tłumaczenie Python 3:źródło
Haskell (
167, 159)Zrobiłem to głównie dla zabawy, jeśli ktoś ma jakieś sugestie, jak to skrócić, chętnie je usłyszę :)
Edycja: Naprawiono problem wskazany mi w komentarzach (dodano 11 bajtów).
Edycja 2: Utworzono funkcję pomocniczą do testowania predykatów przy użyciu strażników zainspirowanych przez user13350, usuwając 8 bajtów.
źródło
][
działa ( wskazane przez użytkownika 13350 )Stax ,
1411 znakówUruchom i debuguj
Kredyt @recursive za -3 bajty.
Odpowiednik ASCII:
Usuń wszystkie znaki z wyjątkiem
[]
, a następnie usuń,[]
aż łańcuch się nie zmieni. Zwraca,1
jeśli ostatni ciąg jest pusty.źródło
.[]|&
do filtrowania znaków, a następnie ponownie użyć literału dla 11