Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

INTERPRETEUR BRAINFUCK


Information sur la source

Catégorie :Astuces Classé sous : interpreteur, brainfuck, machine, turing, Complet Niveau : Débutant Date de création : 21/08/2008 Date de mise à jour : 22/08/2008 06:26:44 Vu / téléchargé: 2 996 / 55

Note :
9,8 / 10 - par 5 personnes
9,80 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (26)
Ajouter un commentaire et/ou une note


Description

sur cette source, je vous presente trois interpreteurs brainfuck.

le premier sans preprocessing

le second, est plus rapide, il evite une boucle.

le troisime est plus un compilateur brainfuck vers php.
 

Source

  • <?php
  • $stdin = fopen('php://stdin', 'r') or die ('erreur etrange');
  • /**
  • * @brief fonction d'entree
  • * renvoie le caractere ascii du caractere suivant de stdin.
  • * @return int
  • */
  • function prompt(){
  • global $stdin;
  • return ord(fread($stdin, 1));
  • }
  • /**
  • * @brief fonction qui interprete un code brainfuck
  • * solution sans preprocessing
  • * @param $code le code a interpreter
  • */
  • function brainfuck_verbeux($code){
  • $code_len = strlen($code);
  • $mem = array();
  • $indice_memoire = 0;
  • for ($i=0;$i<$code_len;$i++){
  • if (!isset($mem[$indice_memoire])) $mem[$indice_memoire]=0;
  • else {
  • // les valeurs sont comprises entre 0 et 256.
  • $mem[$indice_memoire] = (256 + $mem[$indice_memoire] ) % 256;
  • }
  • switch($code[$i]){
  • case '>': $indice_memoire++; break;
  • case '<': $indice_memoire--; break;
  • case '.': echo chr($mem[$indice_memoire]); break; // on affiche la valeur
  • case ',': $mem[$indice_memoire]=prompt(); break;
  • case '+': $mem[$indice_memoire]++; break; // on incremente la valeur
  • case '-': $mem[$indice_memoire]--; break; // on decremente la valeur
  • case ']':
  • $n = 1; // on doit remonter $n [ en arriere
  • while ($n){
  • $i --; // on cherche en arriere
  • if ($code[$i]==']') $n++; // si on rencontre un ], alors on attend un [ de plus
  • else if ($code[$i]=='[') $n--; // si on trouve un [. alors on en attend un de moins
  • } $i--; // on "jump" devant le [ correspondant.
  • break;
  • case '[':
  • if ( $mem[$indice_memoire] == 0 ){
  • $n = 1; // on doit monter $n ] en avant
  • while ($n){
  • $i ++;
  • if ($code[$i]=='[') $n++; // si on rencontre un [, alors on attend un ] de plus
  • else if ($code[$i]==']') $n--; // si on trouve un ]. alors on en attend un de moins
  • } // ici, on a pas de $i-- parce-qu'on jump apres le ]
  • } break;
  • }
  • }
  • }
  • /*
  • la version ci dessus est une version legerement naive.
  • On peut faire plus fin : eviter les boucles plus haut.
  • Celles qui gerent les [ ].
  • Pour les eviter, il faut resoudre les [] en preprocessing,
  • pour cela, il nous suffit d'utiliser une pile.
  • quand on croise un [, on l'empile, quand on croise un ],
  • on depile et on a le couple.
  • */
  • /**
  • * @brief fonction qui interprete un code brainfuck
  • * solution avec preprocessing ( relier les [ aux ] )
  • * @param $code le code a interpreter
  • */
  • function brainfuck($code){
  • $code_len = strlen($code);
  • // on gere les jumps ( [] )
  • $jmp = array();
  • $tmp = array();
  • for ($i=0;$i<$code_len;$i++){
  • if ($code[$i] == '[') array_push($tmp, $i);
  • else if ($code[$i] == ']'){
  • $start = array_pop($tmp);
  • $jumps[$start] = $i;
  • $jumps[$i] = $start - 1;
  • }
  • }
  • // on interprete
  • $mem = array();
  • $indice_memoire = 0;
  • for ($i=0;$i<$code_len;$i++){
  • if (!isset($mem[$indice_memoire])) $mem[$indice_memoire]=0;
  • else {
  • // les valeurs sont comprises entre 0 et 256.
  • $mem[$indice_memoire] = (256 + $mem[$indice_memoire] ) % 256;
  • }
  • switch($code[$i]){
  • case '>': $indice_memoire++; break;
  • case '<': $indice_memoire--; break;
  • case '.': echo chr($mem[$indice_memoire]); break;
  • case ',': $mem[$indice_memoire]=prompt(); break;
  • case '+': $mem[$indice_memoire]++; break;
  • case '-': $mem[$indice_memoire]--; break;
  • case ']': $i = $jumps[$i]; break;
  • case '[': if ( $mem[$indice_memoire] == 0 ) $i = $jumps[$i]; break;
  • }
  • }
  • }
  • function brainfuck_compilateur($str){
  • $checktab='if(!isset($tab[$pos])) $tab[$pos]=0;';
  • $replace = array(
  • '+'=>'$tab[$pos] = ($tab[$pos]==255)?0:($tab[$pos]+1);',
  • '-'=>'$tab[$pos] = ($tab[$pos]==0)?255:($tab[$pos]-1);',
  • '>'=>'$pos++;'.$checktab,
  • '<'=>'$pos--;'.$checktab,
  • '['=>'while($tab[$pos]){',
  • ']'=>'}',
  • '.'=>'echo chr($tab[$pos]);',
  • ','=>'$tab[$pos]=prompt();',
  • );
  • for ($i=0, $code='$tab = array(0); $pos = 0;', $len = strlen($str); $i<$len; $i++)
  • if (isset($replace[$str[$i]]))
  • $code.=$replace[$str[$i]]."\n";
  • eval ($code);
  • }
  • brainfuck_verbeux(
  • '++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.');
  • brainfuck_verbeux(',>,<+>+<.>.');
  • ?>
<?php

$stdin = fopen('php://stdin', 'r') or die ('erreur etrange');
/**
 * @brief fonction d'entree
 * renvoie le caractere ascii du caractere suivant de stdin.
 * @return int
 */
function prompt(){
  global $stdin;
  return ord(fread($stdin, 1));
}

/**
 * @brief fonction qui interprete un code brainfuck
 * solution sans preprocessing
 * @param $code le code a interpreter
 */
function brainfuck_verbeux($code){
  $code_len = strlen($code);
  $mem = array();
  $indice_memoire = 0;
  for ($i=0;$i<$code_len;$i++){
    if (!isset($mem[$indice_memoire])) $mem[$indice_memoire]=0;
    else {
       // les valeurs sont comprises entre 0 et 256.
      $mem[$indice_memoire] = (256 + $mem[$indice_memoire] ) % 256;
    }
    switch($code[$i]){
      case '>': $indice_memoire++; break;
      case '<': $indice_memoire--; break;
      case '.': echo chr($mem[$indice_memoire]); break; // on affiche la valeur
      case ',': $mem[$indice_memoire]=prompt(); break;
      case '+': $mem[$indice_memoire]++; break; // on incremente la valeur
      case '-': $mem[$indice_memoire]--; break; // on decremente la valeur
      case ']':
        $n = 1; // on doit remonter $n [ en arriere
        while ($n){
          $i --; // on cherche en arriere
          if ($code[$i]==']') $n++; // si on rencontre un ], alors on attend un [ de plus
          else if ($code[$i]=='[') $n--; // si on trouve un [. alors on en attend un de moins
        } $i--; // on "jump" devant le [ correspondant.
        break;
      case '[':
        if ( $mem[$indice_memoire] == 0 ){
          $n = 1; // on doit monter $n ] en avant
          while ($n){
            $i ++;
            if ($code[$i]=='[') $n++; // si on rencontre un [, alors on attend un ] de plus
            else if ($code[$i]==']') $n--; // si on trouve un ]. alors on en attend un de moins
          } // ici, on a pas de $i-- parce-qu'on jump apres le ]
      } break;
    }
  }
}

/*
la version ci dessus est une version legerement naive.
On peut faire plus fin : eviter les boucles plus haut.
Celles qui gerent les [ ].
Pour les eviter, il faut resoudre les [] en preprocessing,
pour cela, il nous suffit d'utiliser une pile.

quand on croise un [, on l'empile, quand on croise un ],
on depile et on a le couple.
*/

/**
 * @brief fonction qui interprete un code brainfuck
 * solution avec preprocessing ( relier les [ aux ] )
 * @param $code le code a interpreter
 */
function brainfuck($code){
  $code_len = strlen($code);
  // on gere les jumps ( [] )
  $jmp = array();
  $tmp = array();
  for ($i=0;$i<$code_len;$i++){
    if ($code[$i] == '[') array_push($tmp, $i);
    else if ($code[$i] == ']'){
      $start = array_pop($tmp);
      $jumps[$start] = $i;
      $jumps[$i] = $start - 1;
    }
  }
  // on interprete
  $mem = array();
  $indice_memoire = 0;
  for ($i=0;$i<$code_len;$i++){
    if (!isset($mem[$indice_memoire])) $mem[$indice_memoire]=0;
    else {
       // les valeurs sont comprises entre 0 et 256.
      $mem[$indice_memoire] = (256 + $mem[$indice_memoire] ) % 256;
    }
    switch($code[$i]){
      case '>': $indice_memoire++; break;
      case '<': $indice_memoire--; break;
      case '.': echo chr($mem[$indice_memoire]); break;
      case ',': $mem[$indice_memoire]=prompt(); break;
      case '+': $mem[$indice_memoire]++; break;
      case '-': $mem[$indice_memoire]--; break;
      case ']': $i = $jumps[$i]; break;
      case '[': if ( $mem[$indice_memoire] == 0 ) $i = $jumps[$i]; break;
    }
  }
}

function brainfuck_compilateur($str){
  $checktab='if(!isset($tab[$pos])) $tab[$pos]=0;';
  $replace = array(
    '+'=>'$tab[$pos] = ($tab[$pos]==255)?0:($tab[$pos]+1);',
    '-'=>'$tab[$pos] = ($tab[$pos]==0)?255:($tab[$pos]-1);',
    '>'=>'$pos++;'.$checktab,
    '<'=>'$pos--;'.$checktab,
    '['=>'while($tab[$pos]){',
    ']'=>'}',
    '.'=>'echo chr($tab[$pos]);',
    ','=>'$tab[$pos]=prompt();',
  );
  for ($i=0, $code='$tab = array(0); $pos = 0;', $len = strlen($str); $i<$len; $i++)
    if (isset($replace[$str[$i]]))
      $code.=$replace[$str[$i]]."\n";
  eval ($code);
}

brainfuck_verbeux(
'++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.');
brainfuck_verbeux(',>,<+>+<.>.');

?>

Conclusion

branifuck powaaa
 

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Historique

22 août 2008 06:26:45 :
ajout de la troisieme fonction.

Commentaires et avis

signaler à un administrateur
Commentaire de webdeb le 21/08/2008 09:07:26

Yeah faut que je teste ça juste pour le fun ^^

signaler à un administrateur
Commentaire de codefalse le 21/08/2008 10:18:43 administrateur CS

Mais qui code en ca !!! :D

Je testerais bien ton code mais chuis trop fainéant pour me brainfucker mon cerveau :D

signaler à un administrateur
Commentaire de djmmix le 21/08/2008 12:25:14

je connaissai pas le brainfuck,j'ai fait quelque recherche (wiki ^^')
langage simple mais dur a mettre en oeuvre c'est le cas de le dire  faut ce bruler les neurone avec sa jolie source :)

PS:ta écris "Hello World!"  :p

signaler à un administrateur
Commentaire de Teclis01 le 21/08/2008 12:29:26 9/10

Ah la masturbation intellectuelle :)
Rien de tel pour se muscler la matière grise et arriver a lire n'importe quel code plus facilement ^^
J'avais jeter un oeil sur ces langages il y a quelques temps mais pas eu le temps de me poser vraiment dessus dû à l'intérêt minime dans le métier.
Ceci dit c'est marrant de voir qu'il y ait des secoués comme moi qui regarde ça et pire ...font un interpréteur ;)
Non sans rire j'aime beaucoup et a quoi bon faire que des trucs utiles et lisibles quand on peut faire dans l'inutile, l'illisible mais surtout indispensable ^_^
Merci à toi coucou747 :)

signaler à un administrateur
Commentaire de coucou747 le 21/08/2008 15:49:26

merci :)

codefalse, on a vu un mec au concours google code jam contest, il a resolu au moins un exo en brainfuck.

signaler à un administrateur
Commentaire de nicomilville le 21/08/2008 18:40:39 10/10

Salut coucou747,

Belle source...

Moi aussi je vais la tester juste pour voir ce que je peus faire en brainfuck un peut plus difficile qu'un Hello World! lol

@codefalse : le brainfuck malgrès son nom n'est pas un langage difficile a apprendre (j'y suis arrivé en 20 minutes en déchifrant un message de pysco68...), il n'y a que 8 carractère possible...

Bon après c'est vrai qu'il faut vraiment bien connaitre la table de carractère ascii...

a++

PS : 10/10

signaler à un administrateur
Commentaire de codefalse le 21/08/2008 18:59:23 administrateur CS 10/10

Ca doit être sympa un livre en brainfuck :D

J'avais pas noté avant, alors voila c'est chose faite :)

signaler à un administrateur
Commentaire de nicomilville le 21/08/2008 19:02:40

lol, pas conseillé par contre ça peut être utile pour les mot de passes ou plutot pour les message qu'on veut pas que tout le monde puisse lire...

a++

PS : ça doit être chaud d'écrire un livre ou un programme en brainfuck...

signaler à un administrateur
Commentaire de coucou747 le 21/08/2008 19:11:49

il y a quelques mois, je reflechissais sur la facon de "compiler" un pseudo langage en brainfuck

c'est _vraiment_ pas simple...

signaler à un administrateur
Commentaire de Optitech le 22/08/2008 13:10:00

> branifuck powaaa

Je viens de trouvé le langage qui me fait aimé CamL

signaler à un administrateur
Commentaire de coucou747 le 22/08/2008 17:37:21

c'est tres bien le caml, on peut en faire des choses super !

signaler à un administrateur
Commentaire de nicomilville le 22/08/2008 17:39:26

A bon, on peut faire quoi en CAml ? quelle différence avec l'Ocaml ?

a++

signaler à un administrateur
Commentaire de coucou747 le 22/08/2008 18:00:55

pour faire simple, sisons qu'il y a plusieurs caml, notement l'ocaml et le camllight.

l'ocaml est un langae imperatif, fonctionnel et objet. On peut en faire des choses tres interessantes, d'une facon totalement differente d'autres langages.

signaler à un administrateur
Commentaire de nicomilville le 22/08/2008 18:07:52

ok, merci, j'ai entendu dire que c'est un langage dur et très mathématique...

J'ai également entendu dire que l'ocaml est utilisé dans la sécurité...

a++

signaler à un administrateur
Commentaire de coucou747 le 22/08/2008 18:23:45

c'est un langage assez mathematique oui, mais c'est pas un langage difficile, regarde, meme moi j'y arrive :)

tu peux regarder ici :
http://www.codyx.org/snip_lang_objectivecaml_45.aspx

si tu veux continuer une discution ocaml, tu peux creer un topic dans le bar et m'envoyer l'adresse en mp, ca sera probablement moins poluant :)

signaler à un administrateur
Commentaire de Optitech le 22/08/2008 18:31:48

Caml dur ... oui quand on à jamais touché à un langage fonctionnel et FORTEMENT typé (ce qui est super), mais une fois que tu y a touché c'est assez simple. Une chose important pour faire du Caml : "Il faut avoir confiance à la récurcivité"

Sinon pour ta source Coucou747 (non là il nul le jeu de mot que je viens d'avoir en tête), code code et super ! J'ai hate de me lancé dans le brainfuck pour le testé à font :)

signaler à un administrateur
Commentaire de yoman64 le 22/08/2008 22:42:24

Hello,

Une toute petite question, pourquoi tu ouvre un pointeur vers le stdin alors que php en initialise un directement, à savoir STDIN ?

Je me demande surtout si il y a une raison spécifique à ce choix, si STDIN a volontairement été oublié :P


Sinon excellente source, comme toujours, bien que je sois trop paresseux pour la tester, j'ai quand même pris la peine de lire le code ^^ :)

signaler à un administrateur
Commentaire de coucou747 le 22/08/2008 22:48:40

ah non, j'avais pas vu STDIN, et j'avais rien vu sur php.net pour faire autrement. je testerais ca plus tard, la je suis sur une version ocaml de "manipulation de code brainfuck"

signaler à un administrateur
Commentaire de Optitech le 23/08/2008 10:49:51

>  je testerais ca plus tard, la je suis sur une version ocaml de "manipulation de code brainfuck"

LoL

signaler à un administrateur
Commentaire de Skreo le 25/08/2008 10:49:53 10/10

Sympa ;-)
J'avais fait un interpréteur comme ça (ou plutôt un compilateur) il y a un peu plus d'un an : http://www.skreo.net/article-2905-21372-interpreteur-de-brainfuck.html

signaler à un administrateur
Commentaire de tatactic le 25/08/2008 12:23:49

Pour ceux que ça peut intéresser il y a une machine de Turing virtuelle appelée "Visual Turing" (version 1 et 2).
Bon amusement.
J'espère que ça en amusera quelques uns.
Nico

signaler à un administrateur
Commentaire de Alain Proviste le 06/09/2008 02:09:37 administrateur CS

puisqu'effectivement un interpreteur brainfuck est très exactement equivalent à une machine de turing dont il est l'exemple le plus représentatif

signaler à un administrateur
Commentaire de exar le 14/02/2009 09:44:43 10/10

Amusant !  Comme le disent TATCTIC et ALAIN PROVISTE (qui me rappelle le pédiatre chez qui mes parents m'envoyaient quand j'étais gamin et qui s'appelle Provis...  Pour la petite histoire...), il s'agit d'une machine de Turing.  Il y aurait moyen de faire aussi cela, par exemple, avec des lettres, des chiffres, voire, pourquoi pas, des notes de musique.
Bien foutu, bravo !

signaler à un administrateur
Commentaire de coucou747 le 14/02/2009 12:18:35

merci :)

signaler à un administrateur
Commentaire de exar le 14/02/2009 12:43:12

Mais de rien !  Tu as bien fait ça !  Ton implémentation d'une machine de Turing est originale en PHP, c'est ce qui lui donne son intérêt.  On est parfois étonné du langage de prog utilisé pour résoudre un problème.  Ainsi, j'ai une fois vu un package PL/SQL Oracle qui résolvait des SUDOKU...  Ce n'est pas ce que j'aurais choisi comme langage (même si je le connais sur le bout des doigts), mais ça fonctionne !
Bonne continuation sur la même voie !
A+ !

signaler à un administrateur
Commentaire de coucou747 le 14/02/2009 12:48:27

le plus fun que j'avais vu pour resoudre un sudoku, c'etait des "depots" APT un peu etranges : ils se servaient de la resolution des dependances d'apt comme d'un systeme de resolution par contraintes, et ils resolvaient des sudokus avec ca :)

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

acces ressources web [ par elanspeech ] Bonjour,J'ai mon site internet sur une machine.J'aimerais a partir d'une page de mon site pointer sur un fichier stocke sur une autre machine de mon r valider une date saisie dans un champ avec la date de la machine [ par cba ] cbaje rentre une date dans un champ d'un formulaireex on est le 05/04/03 (date machine)je saisis dans le formulaire la date 060403 ce champ correspon tester la presence de machine sur un reseau [ par Elkaire ] J'aimerais savoir comment faire pour detecter la présence d'une machine afin d'en obtenir un listing en vu de choisir sur laquelle je me connecte. J'a Nom machine [ par Bruto ] j'ai trouvé sur le site php.net la possibilité de récupéré le nom de la machine&lt;?php$hostname = gethostbyaddr($_SERVER['REMOTE_ADDR']); print $hos opendir et readdir sur la machine [ par mageonyme ] Bonjour,Je voudrais que les utilisateurs de mon site puissent sélectionner un dossier qu'ils ont sur leur machine pour que l'ensemble du contenu soit Problème avex ftp_put [ par Amine ] Salut,J'ai installé sur ma machine le serveur web EasyPHp et j'ai creé une page php permettant de transferer u fichier depuis la machine client vers l Php, sans Recharger site complet [ par 666BlackDragoon666 ] Alors voila, j'ai cree un site en php , et mon probleme ces ke ken je clique sur un lien bah TOUT le site se recharge, au lieu de charger SEULEMENT la Base MySql distante [ par Dark77 ] Bonjour j'aurai besoin d'acceder a une base mysql distantePar acces j'entend ecrire et lire directemnt dedans exemple la machine 192.168.0.1 execute u Lien sur machine distante (mapping et Cie) [ par skmancuso ] Bonjour,J'ex&#233;cute via l'interm&#233;diaire de la commande system() un ex&#233;cutable sur lequel je transmet 4 param&#232;tres (un chemin d'acc&# problème de planification [ par h_adil ] bonjour, actuellement en stage, j'ai pour mission de mettre en place un planning de fabrication sous access. ce planning consiste a partir des donn&#2


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,936 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.