Brainfuck ist eine außergewöhnliche Programmiersprache, die ursprünglich um 1993 von Urban Müller für den Amiga entwickelt wurde.
Die Sprache arbeitet mit einem Datenarray aus einer interpreterabhängigen Anzahl von Parzellen (in der Regel 10.000 – 30.000) und besteht aus einem Befehlssatz von acht Befehlen, die zur Navigation innerhalb der Zellen, zu deren Manipulation und als Schleifenkonstrukte dienen:
+ inkrementiert die aktuelle Zelle - dekrementiert die aktuelle Zelle > verschiebt den Parzellenzeiger auf die nachfolgende < bzw. vorherige Zelle . gibt das Zeichen der aktuellen Zelle auf der Standardausgabe aus , liest ein Zeichen von der Standardeingabe und speichert dessen ASCII-Wert in der aktuellen Zelle [ Schleifenkonstrukt: Anfang ] Schleifenkonstrukt: Ende
Diese Limitierung macht das Programmieren in Brainfuck recht aufwändig, weshalb (wie auch schon der Name indiziert) die Sprache eigentlich nur eine Spaßsprache ist, aber gerade deshalb doch gerne in der IT-Welt verwendet wird, allerdings meist nur für Signaturen oder ähnliches (vergl. Mindfuck).
Grundlagen der Programmierung in Brainfuck
Anmerkung: Obwohl die Zeichen // wie die aus anderen Programmiersprachen bekannten Kommentare aussehen, sind es keine. Deshalb wird das Pluszeichen in n+1 als ein Inkrementierbefehl ausgewertet. Die unten angegebenen Beispiele funktionieren daher nur, wenn man die Kommentare aus dem Programmtext löscht.
Schleifen
Schleifen beginnen mit [ und enden mit ]. Die Schleife wird solange ausgeführt, wie der Wert der aktuellen Zelle ungleich Null ist. Die einfachste Form ist die Nullschleife, die die aktuelle Zelle dekrementiert, bis diese Null ist:
[-]
Rechenoperationen
- Verschieben des Wertes einer Zelle in die nächste (Inkrementierung der Folgezelle, gleichzeitige Dekrementierung der aktuellen):
[>+<-]
- Kopieren eines Wertes erfolgt durch das verschieben in 2 Folgezellen und anschließendes Zurückverschieben:
>[-]>[-]<<[>+>+<<-] // verschiebe Inhalt von Zelle n nach Zellen n+1 und n+2 [-]>>[<<+>>-] // verschiebe Inhalt von Zelle n+2 nach Zelle n << // gehe wieder auf Zelle n
- Addition. p[1] = p[1] + p[0]; Nebeneffekt: p[0] = 0
[>+<-]
- Subtraktion: p[1] = p[1] - p[0]; Nebeneffekt: p[0] = 0
[>-<-]
- Multiplikation mit einer Konstanten: Es wird eine normale Verschiebung durchgeführt, wobei die Zielzelle nicht jeweils um eins, sondern um den entsprechenden Faktor erhöht wird:
p[1] = p[0] * 5; Nebeneffekt: p[0] = 0 [>+++++<-]
- Multiplikation mit einem Zellenwert: Hier wird der 2. Faktor wiederholt zum Produkt mittels obiger Kopierfunktion addiert:
p[2] = p[0] * p[1]; Nebeneffekt: p[0] = p[3] = 0 [>[>+>+<<-]>>[<<+>>-]<<<-]
- Potenzieren: Eine Zahl mit +++ in eine Zelle zu schreiben, wird spätestens ab zweistelligen Zahlen mehr als aufwändig. Also behilft man sich mittels Potenzen:
p[2] = 5^3 = 125; Nebeneffekt: p[0] = p[1] = 0 +++++[>+++++[>+++++<-]<-]
- Division funktioniert am einfachsten als restlose Division, alles andere resultiert in dem Fall in einer Endlosschleife. Die Idee ist ansonsten dieselbe wie bei der Multiplikation:
p[1] = p[0] / 5; Nebeneffekt: p[0] = 0 [>+<-----]
- Restbehaftete Division in Brainfuck ist hingegen etwas komplizierter:
// Der C-Code zum nachfolgenden Brainfuck-Programm while(p[0]--) { p[1]--; p[2]++; if(p[1] == 0) { p[3]++; p[1] = p[2]; p[2] = 0; } }
// p[2] = p[0] % p[1] // p[3] = p[0] / p[1] // Nebeneffekt: p[0] = 0; p[1] = p[1] - p[0] % p[1] >>[-]>[-]>[-]>[-]<<<<<[->>+<-[>>>]>[[<+>-]>+>>]<<<<<]
Beim Erstellen von Texten und Brainfucksignaturen kommt es dann nur noch darauf an, durch geschickte Verkettungen von Addition und Multiplikation, die ASCII-Werte der Ausgabezeichen möglichst effektiv zu bestimmen.
Variationen von Brainfuck
Hierbei handelt es sich um solche Sprachen, die genau das gleiche wie Brainfuck machen, sich aber in der Bezeichnung für die Befehle unterscheiden. Das ist prinzipiell so einfach, dass sich jeder sein eigenes Brainfuck, mit seinen eigenen Anweisungsbezeichnungen zusammenbasteln könnte. Ook ist das beste Beispiel dafür. Bei Spoon hat sich allerdings der Entwickler mehr dabei gedacht.
Ook
Ook ist eine Brainfuck-Variante für Orang-Utans. Die Designkriterien der Sprache sind:
- Eine Programmiersprache sollte schreib- und lesbar für Orang-Utans sein.
- Die Syntax sollte einfach sein, leicht zu merken und das Wort Monkey (engl. Affe) vermeiden.
- Bananen sind gut.
Ook hat nur drei Syntaxelemente:
Ook. Ook? Ook!
Diese werden zu Zweiergruppen zusammengefasst, die sich daraus ergebenden 9 Möglichkeiten lassen sich wie Brainfucksymbole verwenden (Ook? Ook? wird nicht verwendet). Es gibt inzwischen Ook-Interpreter in Ruby, Python, Perl und C-Sharp sowie einen Ook zu Brainfuck und Brainfuck zu Ook-Konverter in Java und damit bald mehr Ook-Interpreter als Ook-Programme.
Hello World in Ook:
Ook! Ook. Ook! Ook? Ook! Ook! Ook? Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook? Ook! Ook! Ook? Ook!
Spoon
Der Quelltext von Spoon besteht im Normalfall nur aus Nullen und Einsen, alle anderen Zeichen werden ignoriert. Um Ascii-Bilder mit Spoon zu ermöglichen, lassen sich die Nullen und Einsen auch optional durch jeweils zwei andere Zeichen ersetzen.
Die Besonderheit bei Spoon liegt darin, dass ein Feature aus der Datenkompression (siehe Huffman-Code) verwendet wurde. Denn obwohl ein Spoon-Code wesentlich länger ist, als der entsprechende Brainfuck-Code, lässt sich der entsprechend Spooncode wesentlich kürzer darstellen. Das lässt sich an dem Beispiel des Hello World-Codes zeigen:
- Hello World! in Brainfuck:
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>+ +.<<+++++++++++++++.>.+++.------.--------.>+.>.
Das identische Programm in Spoon:
1111111111001000101111111010111111111101011101010110110110110000 0110101100101001010010101111111001010001010111001010010110010100 1101111111111111111100101001000101011100101000000000000000000000 10100000000000000000000000000010100101001010010001010
Das ist optisch gesehen viel länger. Wenn man allerdings die Null-Einser Kombination als Binärfolge sieht, so lässt sie sich in einen 8-Bit-Code (hexadezimal) umsetzen:
FF C8 BF AF FD 75 6D B0 6B 29 4A FE 51 5C A5 94 DF FF F2 91 5C A0 00 00 A0 00 00 02 94 A4 01010
Das Ergebnis ist wesentlich kürzer als der originale Brainfuck-Code. Und obwohl die einzelnen Spoon-Befehle unterschiedlich lang sind, lässt sich aus der Null-Einser Kette ein eindeutiger Code herauslesen.
Die Systematik, die hinter dieser Kompression steckt, lässt sich auf die Häufigkeit der verwendeten Anweisungen zurückführen: Die am häufigsten verwendete Anweisung muss die kürzeste Codierung haben, und die am seltensten gebräuchliche die längste. Normalerweise wird in Komprimierungsverfahren, die auf diese Art und Weise vorgehen, eine dynamische Huffman-Tabelle erstellt. Im Falle von Spoon, wo sich die Verteilung nicht großartig ändert und die Anzahl der verschiedenen Zustände schon von Anfang an feststeht, lässt sich mit einer statischen Huffman-Tabelle arbeiten.
Vergleich der Befehlsbezeichnungen von BF, Ook und Spoon
Ook! | Spoon | Brainfuck | Beschreibung |
Ook. Ook. | 1 | + | den Wert der aktuellen Zelle um 1 erhöhen |
Ook! Ook! | 000 | - | den Wert der aktuellen Zelle um 1 erniedrigen |
Ook. Ook? | 010 | > | eine Zelle nach rechts gehen |
Ook? Ook. | 011 | < | eine Zelle nach links gehen |
Ook! Ook? | 00100 | [ | Schleifenanfang - die Schleife durchlaufen solange der Wert der aktuellen Zelle ungleich 0 ist |
Ook? Ook! | 0011 | ] | Schleifenende - beendet die Schleife, wenn der Wert der aktuellen Zelle ungleich 0 ist |
Ook! Ook. | 001010 | . | den Wert der aktuellen Zelle ausdrucken |
Ook. Ook! | 0010110 | , | einen Wert von der Tastatur in die aktuelle Zelle einlesen |
BF2d
(auch 2dbf)
BF2d (Abk.: Brainfuck2D) ist eine 2-dimensionale Variation von Brainfuck.
Der Programmcode ist mit einer Schnur zu vergleichen, bei der jede Richtungsänderung ein neues Kommando bildet.
Die Zahlen in der Schnur geben die Anzahl der Wiederholungen des Befehls an.
Code-Beispiel für die Ausgabe des Buchstaben: H
* * * *0***** * ** * ** * * *8*** * 0 * * * * * * * * * * *0* * * * * *9**** * * **************
Weiterentwicklungen von Brainfuck
Die folgenden Programmiersprachen sind (fast alle) auch Brainfuck-Kompatibel, was bedeutet, dass sie Brainfuck-Quellcodes verarbeiten können. Sie besitzen jedoch auch Befehle, die über Brainfuck hinausgehen.
BFM (Brainfuck Makro)
L00p
Toadskin
Toadskin ist eine esoterische Programmiersprache, die Bestandteile von Brainfuck und Forth besitzt.
Weblinks
Brainfuck
- Sascha Seidel, NetPanther Tech. Brainfuck Express - Virtual Turing Machine. stellt eine Entwicklungsumgebung mit eigenem Compiler, Werkzeugen, Tutorials, ASCII Tabelle und Informationen zur Historie dar.
- Brainfuck Interpreter mit integriertem Debugger (IDE) für Windows
- Ein vollständiger Brainfuck Interpreter und Compiler für Windows
- Ein ausführliches deutsches Brainfuck Tutorial
- Brian Raiter, Muppetlabs. Brainfuck: An Eight-Instruction Turing-Complete Programming Language. Diese Seite beinhaltet einen Brainfuck Quine.
- Panu Kalliokoski. The Brainfuck Archive hat viele Brainfuck Programme, Quines, und Implementationen.
- Frans Faase. BF is Turing Complete
- Daniel Cristofani. some brainfuck fluff.
- Brainfuck.ca GPL Brainfuck Interpreter und Code Konverter
- Gesammelter Brainfuck-Kram