Brainfuck – Wiki

Brainfuck

Z Wikipedii, wolnej encyklopedii
Skocz do: nawigacji , szukaj

Brainfuck to ezoteryczny język programowania stworzony przez Urbana Müllera około roku 1993 . Nazywany też czasem Brainf*ck, Brainf*** lub po prostu BF.

Spis treści

[ edytuj ] Budowa języka

Celem Müllera było stworzenie języka z jak najmniejszą liczbą instrukcji oraz jak najmniejszego kompilatora . Oryginalny kompilator, napisany na Amigę ma rozmiar 240 bajtów .

Jak sugeruje nazwa, programowanie w tym języku jest trudne. Bez względu na to w Brainfucku można zaimplementować dowolny algorytm, ponieważ język ten jest zupełny w sensie Maszyny Turinga .

Język opiera się o prosty model maszyny, składający się, oprócz programu, z tablicy bajtów (zazwyczaj 30000) zainicjalizowanych zerami oraz wskaźnika do tej tablicy, zainicjalizowanego tak, aby wskazywał na jej pierwszy element.

[ edytuj ] Instrukcje

Brainfuck zawiera 8 następujących jednoznakowych instrukcji:

Znak Znaczenie Odpowiednik w C
> zwiększa wskaźnik o 1 ++p
< zmniejsza wskaźnik o 1 --p
+ zwiększa o 1 w bieżącej pozycji ++(*p)
- zmniejsza o 1 w bieżącej pozycji --(*p)
. wyświetla znak w bieżącej pozycji ( ASCII ) putchar(*p)
, pobiera znak i wstawia go w bieżącej pozycji ( ASCII ) *p=getchar()
[ skacze bezpośrednio za odpowiadający mu ], jeśli w bieżącej pozycji znajduje się 0 while(*p){
] skacze do odpowiadającego mu [ }

Przy czym "bieżąca pozycja" oznacza element w tablicy wskazywany przez wskaźnik (w odpowiednikach w C p oznacza wskaźnik!).

Wszystkie inne znaki są ignorowane, co jest przydatne przy pisaniu komentarzy.

[ edytuj ] Przykłady

[ edytuj ] Hello World!

Następujący program drukuje napis "Hello World!" na ekranie i przechodzi do nowej linii:

++++++++++
[
>+++++++>++++++++++>+++>+<<<<-
] Na początek ustawiamy kilka przydatnych później wartości
>++.               drukuje 'H'
>+.                drukuje 'e'
+++++++.           drukuje 'l'
.                  drukuje 'l'
+++.               drukuje 'o'
>++.               spacja
<<+++++++++++++++. drukuje 'W'
>.                 drukuje 'o'
+++.               drukuje 'r'
------.            drukuje 'l'
--------.          drukuje 'd'
>+.                drukuje '!'
>.                 nowa linia

Dla względów czytelności kod programu został podzielony na kilka linii i zostały dodane komentarze. Brainfuck traktuje wszystkie znaki poza +-<>[], . jako komentarz. Równie dobrze powyższy program można by zapisać jako:

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

[ edytuj ] Trywialne

[ edytuj ] Czyszczenie komórki

[-]

Prosty program, który ustawia wartość w aktualnej komórce na 0. Mówiąc ściślej, tak długo dekrementuje wartość w aktualnej komórce, jak długo jest ona większa od 0.

[ edytuj ] Prosta pętla

, [., ]

Pętla, która pobiera z wejścia kolejne znaki i drukuje je na ekranie tak długo, aż wczytany zostanie znak końca pliku (EOF). W niektórych implementacjach znak EOF ma wartość -1, wtedy odpowiadający program wygląda następująco:

, +[-., +]

[ edytuj ] Poruszanie wskaźnikiem

>, [.>, ]

Ciekawsza wersja poprzedniego programu, tym razem dodatkowo zapisujemy wejście do kolejnych komórek.

[ edytuj ] Dodawanie

[->+<]

Powyższy kod dodaje wartość w aktualnej komórce do następnej komórki. Warto zauważyć, że zeruje to wartość w aktualnej komórce.

[ edytuj ] Wyrażenie warunkowe w pętli

, ----------[----------------------., ----------]

Powyższy program pobiera wejście (małe litery alfabetu angielskiego) zakończone znakiem nowej linii (czyli wciśnięciem entera) i drukuje je, wcześniej zwiększając litery na wielkie.

Na początku wczytujemy pierwszy znak i odejmujemy od niego 10 (wartość znaku liczona jest w kodzie ASCII, znak nowej linii ma wartość ASCII 10). Gdyby wczytano znak nowej linii program zakończyłby się, w innym wypadku odejmujemy od niego 22 (razem z poprzednimi 10 odjęliśmy już 32, czyli różnicę między odpowiednimi małymi i wielkimi literami), drukujemy na ekranie, po czym znowu wczytujemy znak, odejmujemy 10 i wracamy do początku pętli.

[ edytuj ] Kopiowanie wartości z komórki

(Jako że przykłady robią się coraz bardziej skomplikowane przyjmijmy dla ułatwienia, że [0], [1], [2] i tak dalej odnoszą się do kolejnych komórek)

Powiedzmy, że chcemy skopiować wartość z [0] do [1]. Najprostszym sposobem jest intuicyjne:

[->+<]

Niestety, takie wywołanie ustawi wartość w [0] na 0. Aby odzyskać początkową wartość [0] możemy przekopiować [0] do [1] i [2] równocześnie, a następnie kopiując wartość z [2] do [0]. Program realizujący to zadanie wygląda tak:

[->+>+<<]      kopiujemy z (0) do (1) i (2)
>>[-<<+>>]<<   kopiujemy z (2) do (0)

[ edytuj ] Nietrywialne

Poniżej widać proste implementacje podstawowych operacji arytmetycznych. Są one bardzo uproszczone, tzn. wejściem są dwie cyfry, także wynik musi być cyfrą.

[ edytuj ] Dodawanie

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

Program wczytuje dwie jednocyfrowe liczby i drukuje rezultat dodawania. Niestety, program zadziała poprawnie tylko wtedy, gdy rezultat jest cyfrą.

43
 
7

Wczytujemy do [0] pierwszą cyfrę i odejmujemy od niej 48 (kody ASCII dla cyfr 0-9 to 48-57). Odejmowanie to jest zrobione za pomocą prostej pętli: najpierw wstawiamy 6 do [1], a następnie tak długo, jak [1] jest różna od zera odejmujemy 8 od [0], i w końcu odejmujemy 1 od [1]. Następnie wczytujemy drugą cyfrę do [1]. Następna pętla [<+>-] dodaje drugą liczbę do pierwszej i zeruje [1]. Na końcu drukujemy wartość z [0].

[ edytuj ] Mnożenie

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

Podobnie jak poprzednio, jednak tym razem mnożymy zamiast dodawać.

Pierwszą cyfrę przechowujemy w [0], drugą w [1]. Obie zmniejszamy o 48.

Tutaj zaczyna się pętla główna programu. Działamy według zasady: odejmij 1 od [0] po czym dodaj wartość z [1] do [2].

Na końcu dodajemy 48 do [2] i drukujemy rezultat na ekranie.

[ edytuj ] Dzielenie

, >, >++++++[-<--------<-------->>] przechowuje dwie cyfry w (0) i (1) od obu odejmujemy 48
<<[                               powtarzaj dopóki dzielna jest niezerowa
>[->+>+<<]                        kopiuj dzielnik z (1) do (2) i (3) (1) się zeruje
>[-<<-                            odejmujemy 1 od dzielnej (0) i dzielnika (2) dopóki (2) nie jest 0
[>]>>>[<[>>>-<<<[-]]>>]<<]        jeżeli dzielna jest zerem wyjdź z pętli
>>>+                              dodaj jeden do ilorazu w (5)
<<[-<<+>>]                        kopiuj zapisany dzielnik z (3) do (1)
<<<]                              przesuń wskaźnik na (0) i powtórz pętlę
>[-]>>>>[-<<<<<+>>>>>]            kopiuj iloraz z (5) do (0)
<<<<++++++[-<++++++++>]<.         dodaj 48 i drukuj wynik

Po wczytaniu dwóch cyfr powyższy program oblicza ich iloraz (ignorując resztę) i drukuje go na ekranie.

[ edytuj ] Zobacz też

Lista podobnych języków:

[ edytuj ] Linki zewnętrzne


Francuski minister skazany za publiczną obrazę
Sąd w Paryżu uznał Arnauda Montebourga, ministra ds. reindustrializacji w rządzie nowego socjalistycznego prezydenta Francji Francois Hollande'a, za winnego publicznej obrazy za nazwanie szefów spółki żeglugi promowej SeaFrance "łobuzami".



Skazano lekarza, który pomógł CIA znaleźć bin Ladena
Shakil Afridi, lekarz, który pomógł CIA zlokalizować Osamę bin Ladena został skazany w Pakistanie na 33 lata więzienia. Departament Stanu USA uznał, że władze Pakistanu nie miały podstaw, by go uwięzić.



PO i PiS nie poprą projektu SP dot. kont zabezpieczenia zdrowotnego
PO i PiS zapowiedziały, że pracodawca będzie mógł przekazać pracownikowi pieniądze na ochronę zdrowia, które byłyby wolne od podatku i odprowadzania składek. PSL się waha; poparcie zapowiedziały RP i SLD.



10 błędów ustawy refundacyjnej
Ustawa refundacyjna uderza w pacjentów i wprowadza chaos na rynku leków - oceniają eksperci w raporcie "Do trzech razy sztuka - Ustawa Refundacyjna po publikacji trzech pierwszych wykazów". Wyliczają w nim 10 najważniejszych niedoskonałości nowych przepisów.



Tusk i Schulz rozmawiali o Tymoszenko i Euro 2012
Szef Parlamentu Europejskiego Martin Schulz na spotkaniu z premierem Donaldem Tuskiem poinformował, że z jego upoważnienia europoseł Jacek Protasiewicz zajmie się organizacją misji PE obserwacji procesu kasacyjnego b. premier Julii Tymoszenko.



Home Page , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,