Interpreteur brainfuck

Soyez le premier à donner votre avis sur cette source.

Vue 6 833 fois - Téléchargée 133 fois

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 / Exemple :


<?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

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
36
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 :)
Messages postés
286
Date d'inscription
vendredi 5 décembre 2003
Statut
Membre
Dernière intervention
22 avril 2012
1
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+ !
Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
36
merci :)
Messages postés
286
Date d'inscription
vendredi 5 décembre 2003
Statut
Membre
Dernière intervention
22 avril 2012
1
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 !
Messages postés
908
Date d'inscription
jeudi 26 juillet 2001
Statut
Modérateur
Dernière intervention
1 février 2015
2
puisqu'effectivement un interpreteur brainfuck est très exactement equivalent à une machine de turing dont il est l'exemple le plus représentatif
Afficher les 26 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.