< Programmation Brainfuck

Hello World!

Un programme qui affiche "Hello World!" sur l'écran est :

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

Brainfuck est intéressant dans ce cas, un programme "Hello World!" n'est pas facile à écrire ! Et à lire !

Avec un commentaire :

Hello world
++++++++++[>+++++++>++++++++++>+++>+<<<<-]
>++.>+.+++++++..+++.>++.<<+++++++++++++++.
>.+++.------.--------.>+.>.

Remise à zéro de l'octet pointé

[-]

Tant que l'octet est différent de 0, on le décrémente. On arrête donc la boucle ([]) quand il est à 0.

Entrée/Sortie d'un caractère

,.

Prend un caractère du clavier pour l'afficher à l'écran.

Boucle simple

,[.,]

Une boucle qui prend une entrée du clavier et l'affiche à l'écran. Notez qu'on s'attend à avoir un 0 pour marquer la fin de l'entrée (les implémentations peuvent être différentes à ce niveau là).

Manipulation de pointeur

>,[.>,]

Une version améliorée de la boucle précédente dans laquelle on stocke les caractères entrés dans le tableau pour une future utilisation, en déplaçant le pointeur à chaque fois.

Addition

Ce code ajoute l'octet courant (en le détruisant, il sera à 0 à la fin) à l'octet suivant.

[->+<]

Soit Tableau[0] = 2 et Tableau[1] = 8, "[" débute la boucle, "-" et Tableau[0] = 1, ">" on pointe sur l'octet 1, "+" et Tableau[1] = 9, "]" on recommence. À la fin, on aura bien Tableau[0] = 0 ce qui arrête la boucle, et Tableau[1] = 10.

Instructions conditionnelles

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

Ce programme prend un caractère minuscule en entrée et le met en majuscule. Pour arrêter, on tape la touche entrée (code 10 en Brainfuck dans la plupart des compilos).

Au début, on récupère le premier caractère (,) et on lui soustrait immédiatement 10 (10 fois -). Si l'utilisateur a tapé entrée, on a 0 dans l'octet pointé et l'instruction de boucle ([) sautera à la fin du programme. Si le caractère entré n'est pas 10, on assume qu'il est en minuscule et on entre dans la boucle, où on va lui soustraire le nombre 22 (22 fois -), ce qui va faire 32 en tout, et 32 est la différence en ASCII entre la lettre minuscule et la même lettre en majuscule.

On va donc l'afficher, puis on en récupère une nouvelle, et à nouveau on lui soustrait 10. Et on repart au début de la boucle. Si le caractère entrée est un Entrée (10), la boucle s'arrêtera comme on l'a déjà vu, sinon on continue.

Addition

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

Ce programme additionne 2 nombres à un seul chiffre et affiche le résultat si celui-ci n'a aussi qu'un seul chiffre :

4+3

7

(Maintenant les choses vont être un peu plus compliquées. Nous allons nous référer aux octets du tableau ainsi : [0], [1], [2], etc.)

Le premier nombre est entré dans [0], et on lui soustrait 48 pour avoir sa valeur décimale (les codes ASCII pour les chiffres 0-9 sont 48-57). Cela est fait en mettant 6 dans [1] et en utilisant une boucle pour soustraire 8 de [0] autant de fois que dans [1], soit 6 x 8 = 48. C'est une méthode plus commode pour ajouter ou soustraire des grands nombres que de mettre 48 fois "-" dans le programme. Le code qui fait cela est :

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

>++++++ pour mettre 6 dans [1], puis on attaque la boucle, "<" pour revenir sur [0], on soustrait 8, ">" on repasse sur [1], qu'on décrémente et on retourne dans la boucle. On va bien l'exécuter 6 fois, jusqu'à ce que [1] soit à 0.

Ensuite, on récupère le signe plus qu'on met dans [1] ; puis le second chiffre qui va écraser le signe plus.

La boucle suivante [<+>-] fait le vrai boulot, ajoutant le second nombre dans le premier et remettant à zéro [1]. A chaque boucle, il ajoute 1 dans [0] et retire 1 de [1]  ainsi [1] va finir par être à 0 tout ce qui a été ajouté à [0] a été retiré de [1]. Ensuite la touche entrée est mise dans [1]. (Note : il n'y a eu aucun contrôle des entrées.)

Puis le pointeur est remis sur [0], qui est affiché ([0] est maintenant a + (b + 48), puisqu'on n'a pas corrigé b ; ce qui est identique à (a + b) + 48, qui est ce que l'on veut), Maintenant, le pointeur est ramené sur [1], qui contient la touche entrée ; que l'on affiche, et le boulot est fait.

Multiplication

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

Comme le précédent, mais effectue une multiplication, pas une addition.

Le premier nombre est entré dans [0], l'astérisque et le deuxième nombre dans [1] et les 2 nombres sont corrigés en leur soustrayant 48 (notez qu'il n'y a qu'une seule boucle de 8 itérations pour soustraire 6 à chaque itération aux 2 nombres !).

Ensuite on entre dans la boucle de multiplication principale. L'idée de base est qu'à chaque boucle on soustrait 1 de [0] et on ajoute [1] dans le total cumulé gardé en [2] (3 * 2 = 2 + 2 + 2). En particulier : la première boucle cumule [1] dans [2] et [3], tout en remettant [1] à 0. (C'est la manière basique de dupliquer un nombre.) La deuxième boucle remet [3] dans [1], en remettant à 0 [3]. Puis on décrémente [0] et on est à la fin de la boucle principale. A la sortie de cette boucle, [0] contient 0, [1] a encore le 2e nombre, et [2] a le produit des 2 nombres. (Si on veut garder le premier nombre, on peut l'ajouter dans [4] à chaque itération de la boucle principale, puis à la fin de déplacer la valeur de [4] dans [0].)

Exemple : 3 * 2

[0][1][2][3]
3200
1re boucle : >[>+>+<<-]
3111
3022
2e boucle : >>[<<+>>-]
3121
3220
Fin boucle princ : <<<-]
2220
1re boucle : >[>+>+<<-]
2131
2042
2e boucle : >>[<<+>>-]
2141
2240
Fin boucle princ : <<<-]
1240
1re boucle : >[>+>+<<-]
1151
1062
2e boucle : >>[<<+>>-]
1161
1260
Fin boucle princ : <<<-]
0260

Ensuite, il ne reste plus qu'à ajouter 48 au produit, récupérer la touche entrée dans [3], et afficher le produit ASCII et l'entrée qu'on vient juste de stocker.

Cet article est issu de Wikibooks. Le texte est sous licence Creative Commons - Attribution - Partage dans les Mêmes. Des conditions supplémentaires peuvent s'appliquer aux fichiers multimédias.