Mis à jour le 30/12/2014
  • 2 heures
  • Facile
Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Introduction du cours

Bienvenue sur ce cours dédié à la programmation en brainfuck !

Ce cours s'adresse à toutes les personnes étant curieuses de découvrir ce langage minimaliste ! Il ne demande pas du tout de pré-requis, seulement un peu de motivation. Bien sûr, si vous disposez de connaissances en programmation cela vous aidera à avancer plus vite, mais sinon ne vous inquiétez pas, nous n'allons rien voir d'insurmontable. ;)

Alors, vous êtes prêt ? C'est parti !:pirate:

Présentation

Brainfuck (aussi connu sous le nom de Brainf*ck, Brainf*** ou encore de BF pour les plus intimes) est un langage de programmation créé en 1993 par Urban Müller. Les plus anglophiles d'entre vous auront certainement compris son sens littéral.  Venant de "brain" (cerveau) et de "fuck" (baiser), brainfuck signifie  "masturbation intellectuelle".

Mais Urban Müller n'était-il pas un peu masochiste ?

Non pas du tout, en réalité si ce langage n'est pas très facile à décrypter pour un Homme c'est simplement parce que le but d'Urban Müller était de créer un langage de programmation complet qui puisse être implémenté avec le plus petit compilateur possible (240 octets dans sa version 2). Pour ce faire, le brainfuck ne comporte que 8 instructions !

Malgré sa petite taille, le brainfuck est un langage Turing-complet ce qui signifie qu'il est théoriquement possible d'écrire n'importe quel programme en brainfuck. Dans la pratique, le brainfuck ne doit pas être perçu comme un langage ayant pour but de programmer quelconque logiciel, mais il doit être perçu comme un moyen de s'amuser et de relever des défis tout en faisant chauffer les neurones !

C'est bon je suis décidé, je me lance ! Mais de quoi ai-je besoin ?

Vous pouvez tout simplement utiliser un interpréteur sur navigateur comme celui-ci.

Comment ça fonctionne ?

Le principe est relativement simple, vous avez à disposition :

  • un tableau de 30 000 cellules pouvant contenir chacune 1 octet.

  • 1 pointeur qui va permettre de se déplacer dans ce tableau.

  • 8 instructions qui vont permettre entre autres de modifier et d'afficher la valeur d'une cellule.

Vous pouvez donc oublier les noms de variables, les fonctions etc.

Index

0

1

2

3

4

5

6

7

8

Valeur

0

66

111

110

106

111

117

114

33

Le pointeur prend initialement la valeur 0. Pour accéder, par exemple, à l'octet qui a pour indice 3, il suffit donc d'ajouter 3 au pointeur. C'est ainsi que nous pouvons facilement nous déplacer dans le tableau.

Les instructions

Il est temps pour nous de détailler les 8 instructions et par la même occasion de passer à la pratique !

Déplacement du pointeur : < et >

Les instructions "<" et ">" permettent respectivement de décrémenter (retirer 1) et d'incrémenter (ajouter 1) le pointeur. Ces 2 instructions vont donc nous servir à déplacer le pointeur dans le tableau.

Pour se positionner sur la cinquième cellule il suffit donc de faire:

>>>>>

Modification de la valeur d'une cellule : + et -

Les instructions "+" et "-" permettent respectivement d'incrémenter et de décrémenter l'octet sur lequel est positionné le pointeur.

Par exemple pour que la troisième cellule prenne la valeur 5 il suffit de faire :

>>>+++++

Si on demande le debug, cela affiche bien :

Pointer: 3
Value at pointer: 5

Affichage d'une valeur : .

L'instruction "." permet d'afficher la valeur pointée.

Mais alors, s'il n'y a que les instructions + et pour changer une valeur, on ne peut afficher que des nombres ?

Très bonne question, en vérité l'instruction "." n'affiche pas la valeur brute. 

Pour preuve, si vous tapez le code suivant :

+.

Ce code incrémente l'octet courant et l'affiche. On aurait donc pu penser que cela affiche 1. Mais non, cela n'affiche rien car l'instruction "." affiche en réalité la valeur ASCII du nombre. Cela va nous permettre de faire correspondre un nombre décimal avec un caractère.

Pour avoir la correspondance entre le nombre décimal et le caractère, on se sert d'une table ASCII (à prononcer : table à ski :)). 

Table ASCII
Table ASCII

(La colonne hexadécimal ne sera pas utile ici.)

Si nous reprenons l'exemple précédent, on remarque que dans la table, le caractère "1" correspond au code décimal 49. Vous l'avez donc compris, pour afficher 1 il faut donc taper :

+++++++++++++++++++++++++++++++++++++++++++++++++.

Mais c'est bien trop long ! On va devoir faire ça pour chaque  lettre d'une phrase par exemple ?

Non heureusement ! Laissez-moi vous présenter deux autres instructions qui vont nous être très utiles. ;)

Les boucles : [ et ]

Prenons tout d'abord les explications que l'on trouve sur Wikipedia :

[​ : saute à l'instruction après le ] correspondant si l'octet pointé est à 0.

]​ : retourne à l'instruction après le [ si l'octet pointé est différent de 0.

Pour le dire autrement, tant que la cellule pointée a une valeur différente de 0, l'instruction se trouvant entre les [ ] se fait en boucle.

On va donc avoir besoin d'un compteur qui aura pour valeur x. À chaque itération de la boucle, le compteur prendra la valeur x-1. Lorsque x = 0 le programme sort de la boucle.

Si nous reprenons l'exemple précédent pour simplement afficher 1, nous pouvons faire :

++++++++++      On initialise le compteur à 10
[
    >           On va dans l'octet que l'on veut afficher
    +++++       Et à chaque itération on l'incrémente de 5 pour avoir 50
    <-          On décrémente le compteur
]    
>-.             On a plus qu'à retirer 1 pour avoir 49 et l'afficher !

N'hésitez pas à vous entraîner, c'est avec la pratique qu'on apprend !

Prenons un autre exemple qui montre encore plus l'intérêt des boucles : essayons d'afficher "Hello".

Voilà une structure que l'on peut adopter :

Index

0

1

2

3

4

5

Valeur

Compteur 

72

101

108

108

111

Premièrement, on va affecter les valeurs aux cellules à la dizaine près grâce à une boucle :

++++++++++[        Compteur à 10
    >+++++++       70
    >++++++++++    100
    >+++++++++++   110
    >+++++++++++   110
    >+++++++++++   110
    <<<<<-         On reviens à l'indice 0 et on décrémente le compteur
]

On obtient donc le tableau suivant :

0

1

2

3

4

5

0

70

100

110

110

110

Il ne reste plus qu'à affiner et à afficher !

++++++++++[        Compteur à 10
    >+++++++       70
    >++++++++++    100
    >+++++++++++   110
    >+++++++++++   110
    >+++++++++++   110
    <<<<<-         On revient à l'indice 0 et on décrémente le compteur
]

>++.      70+2=72
>+.       100+1=101
>--.      110-2=108
>--.      110-2=108
>+.       110+1=111

On peut aussi l'écrire comme ceci :

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

Je me répète mais n'hésitez pas à vous entraîner !

Nous avons vu ensemble 7 instructions, il en reste donc... une seule ! Voyons-la sans tarder :)

Écrire une valeur: ,

L'instruction "," va nous permettre d'écrire un caractère rentré par l'utilisateur à l'emplacement du pointeur.

Les caractères sont stockés dans un buffer, l'écriture se fait caractère par caractère.

Essayez maintenant d'afficher tout ce que l'utilisateur rentre dans le champ input !

Correction :

,[.,]

Le code est assez simple à comprendre : on lit le premier caractère puis on affiche tant que la valeur lue est différente de 0.

Quelques astuces

Remise à zéro de l'octet pointé

[-]

Cela décrémente la valeur jusqu'à ce qu'elle soit égale à 0.

Exemple de certificat de réussite
Exemple de certificat de réussite