Brainfuck

minimalistische esoterische Programmiersprache
Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 22. Dezember 2004 um 15:11 Uhr durch 217.225.110.28 (Diskussion) (Den Divisor vor einer Division auf 0 zu setzen ist Nicht Klug(tm).). Sie kann sich erheblich von der aktuellen Version unterscheiden.

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

 [>+<-]
  • 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
 [>+<-]
 [>-<-]
  • 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:

  1. Eine Programmiersprache sollte schreib- und lesbar für Orang-Utans sein.
  2. Die Syntax sollte einfach sein, leicht zu merken und das Wort Monkey (engl. Affe) vermeiden.
  3. 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.

Brainfuck

Ook

Spoon

BF2d