2014-07-21 16 views
6

Pracuję więc nad programem, który wczytuje plik, a następnie ponownie go wypuszcza, ale mam problem z zatrzymaniem programu na wejściu koniec pliku. Chcę, aby zatrzymał się na konkretnej postaci, takiej jak "0" lub "$", czy cokolwiek innego, ponieważ nie można odczytać jednego znaku NULL w moim interpretatorze brainf. Oto kod do tej pory:Wykonywanie instrukcji if (x == y) w Brainfuck

>+[>,][<.] 

Problem zaczyna się [>,] ponieważ wejście nie może być NULL to pętla nigdy się nie kończy.

Jak więc wstawić instrukcję if, która zakończy tę pętlę, jeśli kiedykolwiek dojdzie do określonego wcześniej znaku końcowego?

Odpowiedz

5

Poniższy kod jest równoważny do kodu, z tym że zatrzyma się, gdy wartość wejścia wynosi 1 (niedrukowane w ASCII). < pomiędzy pętlami jest reuired ponieważ ostatnia wartość to 0.

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

To zmniejsza wartość po wejściu, sprawdza, czy jest to 0, a pętle z powrotem, jeśli tak nie jest. Jeśli zostanie zwinięty, musi ponownie zwiększyć wskaźnik, aby cofnąć dekrementację. Tablicy próbek może być:

00 02 H e l l o _ W o r l d 00 
             ^

Jednakże [<.] drukuje odwrotnego łańcucha (po której niedrukowalny 1). Sam łańcuch mogą być drukowane przez przesunięcie kursora na początek i do przodu od tego, jak pokazano w tym kodzie:

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

w tym kodzie, że [<] zatrzymuje się po osiągnięciu indeks 0, >> przenosi się do indeksu 2 (ciąg znaków), a [.>] wysyła znaki, aż osiągnie 0 na końcu.

Jeśli chcesz użyć innego znaku ASCII, na przykład spacji (32), powtórz znaki + i - w obrębie pierwszej pętli, które wiele razy. (Uwaga: ten kod da wartości poniżej 0, jeśli w danych wejściowych są jakieś znaki mniejsze niż 32).

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

Zacznij od znaczącego charakteru - chodźmy do $, ponieważ jest to ASCII 36:

++++++[->++++++<]> 

Czytaj wejście, kopiowanie zarówno wejście jak i znaczącą postacią ponad dwukrotnie, z drugiej znaczącą postać w koniec:

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

dla struktury takie jak to:

┌───┲━━━━━━━┱───────┬───────┬───┐ 
│ $ ┃ blank ┃ input │ input │ $ │ 
└───┺━━━━━━━┹───────┴───────┴───┘

odjąć pierwszy $ od pierwszego input:

<[->>-<<]>> 

Jeśli to nie zero, przesunąć do przodu trzy razy do pustej komórce po kopią $, a następnie przesunąć do tyłu bezwarunkowo, wychodzenia z pętli, gdy wejście było $ i inaczej zostawiając w $, gotowy, aby rozpocząć ponownie:

[>>>]<] 

Po pętli, jesteś w lewo na th e blank dopasowanej postaci. Przejdź do zgodnego znaku wejściowego i usuń go, aby nie był ponownie drukowany, przesuń się pięć razy w tył, aby dotrzeć do nienaruszonej kopii input, a następnie stwórz kopię zapasową (nie musi to być zależne od owijanie tłumaczy i takie, jeśli przesuniesz trochę dalej na początku):

>>[-]<<<<<[<<<<<] 

A następnie wydrukuj je!

>>>>>[.>>>>>] 

W sumie

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

ta jest użyteczna strona pełna BF algorithms że lubię wykorzystać.

Algorytmy, których potrzebujesz, to # 19 (x = x==y) i albo # 28 (if (x) {code}) lub # 30 (if (x) {code1} else {code2}).

Sprawdzanie, czy dwie komórki są sobie równe, jest całkiem proste, więc po prostu skopiuję algorytm if (x) {code1} else {code2} tutaj. temp0 oznacza przejście do komórki i użycie jej jako zmiennej tymczasowej. Ten specyficzny kod wymaga, aby temp0 i temp1 następowały po kolei w pamięci x.

temp0[-]+ 
temp1[-] 
x[ 
code1 
x>-]> 
[< 
code2 
x>->]<<