Interpréter le cerveau ***


113

Ecrivez le programme le plus court dans votre langue préférée pour interpréter un programme brainfuck . Le programme est lu depuis un fichier. L'entrée et la sortie sont l'entrée standard et la sortie standard.

  1. Taille de la cellule: 8bit non signé. Le débordement n'est pas défini.
  2. Taille du tableau: 30000 octets (non encerclé)
  3. Les mauvaises commandes ne font pas partie de l'entrée
  4. Les commentaires commencent par # et s'étendent jusqu'à la fin de la ligne. Les commentaires sont tout ce qui n'est pas dans+-.,[]<>
  5. aucun symbole EOF

Un très bon test peut être trouvé ici . Il lit un nombre puis imprime les nombres premiers jusqu’à ce nombre. Pour empêcher la pourriture de lien, voici une copie du code:

compute prime numbers
to use type the max number then push Alt 1 0
===================================================================
======================== OUTPUT STRING ============================
===================================================================
>++++++++[<++++++++>-]<++++++++++++++++.[-]
>++++++++++[<++++++++++>-]<++++++++++++++.[-]
>++++++++++[<++++++++++>-]<+++++.[-]
>++++++++++[<++++++++++>-]<+++++++++.[-]
>++++++++++[<++++++++++>-]<+.[-]
>++++++++++[<++++++++++>-]<+++++++++++++++.[-]
>+++++[<+++++>-]<+++++++.[-]
>++++++++++[<++++++++++>-]<+++++++++++++++++.[-]
>++++++++++[<++++++++++>-]<++++++++++++.[-]
>+++++[<+++++>-]<+++++++.[-]
>++++++++++[<++++++++++>-]<++++++++++++++++.[-]
>++++++++++[<++++++++++>-]<+++++++++++.[-]
>+++++++[<+++++++>-]<+++++++++.[-]
>+++++[<+++++>-]<+++++++.[-]

===================================================================
======================== INPUT NUMBER  ============================
===================================================================
+                          cont=1
[
 -                         cont=0
 >,
 ======SUB10======
 ----------

 [                         not 10
  <+>                      cont=1
  =====SUB38======
  ----------
  ----------
  ----------
  --------

  >
  =====MUL10=======
  [>+>+<<-]>>[<<+>>-]<     dup

  >>>+++++++++
  [
   <<<
   [>+>+<<-]>>[<<+>>-]<    dup
   [<<+>>-]
   >>-
  ]
  <<<[-]<
  ======RMOVE1======
  <
  [>+<-]
 ]
 <
]
>>[<<+>>-]<<

===================================================================
======================= PROCESS NUMBER  ===========================
===================================================================

==== ==== ==== ====
numd numu teid teiu
==== ==== ==== ====

>+<-
[
 >+
 ======DUP======
 [>+>+<<-]>>[<<+>>-]<

 >+<--

 >>>>>>>>+<<<<<<<<   isprime=1

 [
  >+

  <-

  =====DUP3=====
  <[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<<<

  =====DUP2=====
  >[>>+>+<<<-]>>>[<<<+>>>-]<<< <


  >>>


  ====DIVIDES=======
  [>+>+<<-]>>[<<+>>-]<   DUP i=div

  <<
  [
    >>>>>+               bool=1
    <<<
    [>+>+<<-]>>[<<+>>-]< DUP
    [>>[-]<<-]           IF i THEN bool=0
    >>
    [                    IF i=0
      <<<<
      [>+>+<<-]>>[<<+>>-]< i=div
      >>>
      -                  bool=0
    ]
    <<<
    -                    DEC i
    <<
    -
  ]

  +>>[<<[-]>>-]<<          
  >[-]<                  CLR div
  =====END DIVIDES====


  [>>>>>>[-]<<<<<<-]     if divides then isprime=0


  <<

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

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

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

  >>




  ===================================================================
  ======================== OUTPUT NUMBER  ===========================
  ===================================================================
  [>+<-]>

  [
   ======DUP======
   [>+>+<<-]>>[<<+>>-]<


   ======MOD10====
   >+++++++++<
   [
    >>>+<<              bool= 1
    [>+>[-]<<-]         bool= ten==0
    >[<+>-]             ten = tmp
    >[<<++++++++++>>-]  if ten=0 ten=10
    <<-                 dec ten     
    <-                  dec num
   ]
   +++++++++            num=9
   >[<->-]<             dec num by ten

   =======RROT======
      [>+<-]
   <  [>+<-]
   <  [>+<-]
   >>>[<<<+>>>-]
   <

   =======DIV10========
   >+++++++++<
   [
    >>>+<<                bool= 1
    [>+>[-]<<-]           bool= ten==0
    >[<+>-]               ten = tmp
    >[<<++++++++++>>>+<-] if ten=0 ten=10  inc div
    <<-                   dec ten     
    <-                    dec num
   ]
   >>>>[<<<<+>>>>-]<<<<   copy div to num
   >[-]<                  clear ten

   =======INC1=========
   <+>
  ]

  <
  [
   =======MOVER=========
   [>+<-]

   =======ADD48========
   +++++++[<+++++++>-]<->

   =======PUTC=======
   <.[-]>

   ======MOVEL2========
   >[<<+>>-]<

   <-
  ]

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

  ===================================================================
  =========================== END FOR ===============================
  ===================================================================


  >>>>>>>
 ]
 <<<<<<<<



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

======LF========

++++++++++.[-]
@

Exemple d'exécution:

$ python2 bf.py PRIME.BF 
Primes up to: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 

5
Vous devez clarifier environ 1) la taille de la mémoire 2) la mémoire est encerclée 4) peut-être d'autres détails
Nakilon

3
Je me demande s'il devrait y avoir deux catégories: les programmes qui utilisent eval (ou le shell pour compiler) - et ceux qui ne le font pas.
MtnViewMark

34
J'aimerais voir quelqu'un répondre à cette question dans un brainfuck.
Hannesh

3
Que signifie "pas de symbole EOF"? Que la valeur de la cellule reste inchangée lors de l’essai ,d’EOF? Ou que c'est à nous de choisir une valeur lorsque vous essayez ,EOF? Ou bien le comportement non défini EOF est-il tout à fait?
Martin Ender

3
De même, que devrait-il se passer lorsque quelqu'un essaie de laisser les 30 000 cellules de chaque côté? La tête de la bande doit-elle rester en place ou s'agit-il d'un comportement non défini?
Martin Ender

Réponses:


46

Perl, 120 138

%c=qw(> $p++ < $p-- + D++ - D-- [ while(D){ ] } . print+chrD , D=ord(getc));
$/=$,;$_=<>;s/./$c{$&};/g;s[D]'$b[$p]'g;eval

Cela fonctionne parfaitement: bonjour.bf et primes.bf:

$ perl bf.pl hello.bf
Hello World!
$ perl bf.pl prime.bf
Primes up to: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

Initialisation: l’opcode vers la table de traduction Perl est stocké dans %c. La forme lisible ressemble à ceci:

%c=(
  '>' => '$p++',
  '<' => '$p--',
  '+' => '$b[$p]++',
  '-' => '$b[$p]--',
  '[' => 'while($b[$p]){',
  ']' => '}',
  '.' => 'print chr$b[$p]',
  ',' => '$b[$p]=ord(getc)',
);

Étape 1: Slurp entrée du programme à $_et le transformer en code Perl en utilisant la table de traduction. Les commentaires sont automatiquement supprimés (remplacés par undef) à cette étape.

Étape 2: décompressez toutes les $b[$p]occurrences

Étape 3: Lancez le programme en utilisant eval.


Utilisez simplement la qwsyntaxe de Perl pour définir %cdirectement - bon pour 7 caractères en moins (vous devrez le dire print+chr$b[$p]et ord(getc), bien que)
mob

Je compte 18 sauvés… merci! (Mise à jour dans une minute)
JB

1
@olivecoder De quoi parlez-vous?
JB

La table% c est déclarée et définie dans la première ligne; ses personnages sont parfaitement expliqués.
JB

@JB hey, j'ai accidentellement bloqué le vote sur votre réponse et elle est bloquée. Pouvez-vous modifier cela afin que je puisse inverser le vote à la baisse?
cyclohexanol.

67

Python (aucune évaluation), 317 octets

from sys import*
def f(u,c,k):
 while(c[1]>=k)*u:
  j,u='[]<>+-,.'.find(u[0]),u[1:];b=(j>=0)*(1-j%2*2);c[1]+=b*(j<2)
  while b*c[c[0]]and j<1:f(u,c,k+1);c[1]+=1
  b*=c[1]==k;c[[0,c[0],2][j/2-1]]+=b
  if(j==6)*b:c[c[0]]=ord(stdin.read(1))
  if(j>6)*b:stdout.write(chr(c[c[0]]))
f(open(argv[1]).read(),[-1]+[0]*30003,0)

70
+1 pour lef(u,c,k)
Joel Cornett

9
C'est un beau morceau de bruit, monsieur
globby

-1 octet si vous remplacez while b*c[c[0]]and j<1parwhile b*c[c[0]]*(j<1)
Daniil Tutubalin le

50

Code machine 16 bits 8086: 168 octets

Voici la version encodée en base64 , convertissez-la et enregistrez-la sous «bf.com» et exécutez-la à partir de l'invite de commande Windows: «bf progname»

gMYQUoDGEFKzgI1XAgIfiEcBtD3NIR8HcmOL2LQ/i88z0s0hcleL2DPA86sz/zP2/sU783NHrL0I
AGgyAU14DTqGmAF194qOoAH/4UfDJv4Fwyb+DcO0AiaKFc0hw7QBzSGqT8MmODV1+jPtO/NzDaw8
W3UBRTxddfJNee/DJjg1dPoz7U509YpE/zxddQFFPFt18U157sM+PCstLixbXUxjTlJWXmV+

MODIFIER

Voici un assembleur (style A86) pour créer l'exécutable (j'ai dû faire de l'ingénierie inverse, car j'avais égaré la source originale!)

    add dh,10h                              
    push dx                                 
    add dh,10h                              
    push dx                                 
    mov bl,80h                              
    lea dx,[bx+2]                         
    add bl,[bx]                            
    mov [bx+1],al                         
    mov ah,3dh                              
    int 21h                                 
    pop ds                                 
    pop es                                 
    jb ret                               
    mov bx,ax                              
    mov ah,3fh                              
    mov cx,di                              
    xor dx,dx                              
    int 21h                                 
    jb ret                               
    mov bx,ax                              
    xor ax,ax                              
    repz stosw                                     
    xor di,di                              
    xor si,si                              
    inc ch                                 
program_loop:
    cmp si,bx                              
    jnb ret                               
    lodsb                                    
    mov bp,8                            
    push program_loop
symbol_search:                       
    dec bp                                 
    js ret
    cmp al,[bp+symbols]
    jnz symbol_search
    mov cl,[bp+instructions]
    jmp cx                                 
forward:
    inc di                                 
    ret                                    
increment:
    inc b es:[di]                      
    ret                                    
decrement:
    dec b es:[di]                      
    ret                                    
output:
    mov ah,2                              
    mov dl,es:[di]                            
    int 21h                                 
    ret                                    
input:
    mov ah,1                              
    int 21h                                 
    stosb                                    
backward:
    dec di                                 
    ret                                    
jumpforwardifzero:
    cmp es:[di],dh                            
    jnz ret                               
    xor bp,bp
l1: cmp si,bx                              
    jnb ret
    lodsb                                    
    cmp al,'['                              
    jnz l2
    inc bp
l2: cmp al,']'                              
    jnz l1
    dec bp                                 
    jns l1
    ret                                    
jumpbackwardifnotzero:
    cmp es:[di],dh                            
    jz  ret
    xor bp,bp
l3: dec si                                 
    jz  ret
    mov al,[si-1]                         
    cmp al,']'
    jnz l4
    inc bp  
l4: cmp al,'['                              
    jnz l3
    dec bp                                 
    jns l3
    ret                                    
symbols:
    db '><+-.,[]'
instructions:
    db forward and 255
    db backward and 255
    db increment and 255
    db decrement and 255
    db output and 255
    db input and 255
    db jumpforwardifzero and 255
    db jumpbackwardifnotzero and 255

J'ai ajouté une version du code source du programme. Je viens de remarquer que les caractères non-bf entraînent la fermeture du programme plutôt que son ignorance. Facile à résoudre et je laisserai cela comme un exercice pour que les gens le fassent eux-mêmes.
Skizz

Je me souviens que j'ai reçu la version Linux ELF de 166 octets, il y a 10 ans, ici muppetlabs.com/~breadbox/software/tiny
Emmanuel

39

brainfuck , 843 691 octets

Edit: a décidé de revenir sur cette question et a trouvé un nombre surprenant de façons de jouer au golf hors octets

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

Ceci prend une entrée sous la forme code!inputoù le !inputest optionnel. Il simule également les cellules négatives sans utiliser de cellules négatives et peut stocker jusqu’à des (30000-(length of code+6))/2cellules.

Essayez-le en ligne!


Juste pour m'assurer que j'ai bien compris, si je exécutais ce programme avec ce programme, je pourrais l'imbriquer sur 5 niveaux de profondeur tout en gérant des entrées de code de longueur 262.
Draco18s

@ Draco18s Je suppose que vous auriez épuisé les 30000 cellules auparavant, car la taille de chaque interpréteur imbriqué augmente de façon exponentielle. Je pense que vous obtiendrez 2, peut-être 3 niveaux de profondeur
Jo King

Même 3 profonds serait hilarant bête.
Draco18s

27

Ruby 1.8.7, 188 185 149 147 caractères

eval"a=[i=0]*3e4;"+$<.bytes.map{|b|{?.,"putc a[i]",?,,"a[i]=getc",?[,"while a[i]>0",?],"end",?<,"i-=1",?>,"i+=1",?+,"a[i]+=1",?-,"a[i]-=1"}[b]}*";"

Version assez lisible:

code = "a = [0] * 3e4; i = 0;"
more_code ARGF.bytes.map {|b|
  replacements = {
    ?. => "putc a[i]",
    ?, => "a[i] = getc",
    ?[ => "while a[i] > 0 do",
    ?] => "end",
    ?< => "i -= 1",
    ?> => "i += 1",
    ?+ =>"a[i]+=1",
    ?- =>"a[i]-=1"
  }
  replacements[b]
}.join(";")
eval code+more_code

Comme vous le voyez, je vous ai volé sans vergogne votre idée de traduire en langage hôte puis d’utiliser eval pour l’exécuter.


Vous pouvez rasera un octet octet comparant à zéro >0plutôt que de tester l' égalité: !=0. Les spécifications disent non signé, et le débordement n'est pas défini.
lâche anonyme

3e4travaillera également par opposition à30000
lâche anonyme

@Charlie: Merci. Bien que pour être juste il n'a pas dit "non signé" quand j'ai écrit le code. Honnêtement, je ne savais pas que vous pourriez écrire 3e4 cependant. C'est un très bon point et bon à savoir.
sepp2k

File.read($*.pop).bytes-> $<.bytesdevrait aussi marcher
Arnaud Le Blanc

1
Ruby 1.8.7 a une syntaxe encore plus courte pour construire un hachage littéral:, {?a,"foo"}ce qui équivaut à {?a=>"foo"}. Et le test ici montre que vous pouvez réellement remplacer File.read($*.pop).bytesavec $<sans aucun problème. De même, tout aligner sur quelque chose comme eval"a[0]..."+$<.bytes.map{?.,"putc a[i]",...}*";"raccourcit la solution de quelques caractères supplémentaires .
Ventero

26

Lambda Calcul binaire 112

Le programme affiché dans le vidage hexadécimal ci-dessous

00000000  44 51 a1 01 84 55 d5 02  b7 70 30 22 ff 32 f0 00  |DQ...U...p0".2..|
00000010  bf f9 85 7f 5e e1 6f 95  7f 7d ee c0 e5 54 68 00  |....^.o..}...Th.|
00000020  58 55 fd fb e0 45 57 fd  eb fb f0 b6 f0 2f d6 07  |XU...EW....../..|
00000030  e1 6f 73 d7 f1 14 bc c0  0b ff 2e 1f a1 6f 66 17  |.os..........of.|
00000040  e8 5b ef 2f cf ff 13 ff  e1 ca 34 20 0a c8 d0 0b  |.[./......4 ....|
00000050  99 ee 1f e5 ff 7f 5a 6a  1f ff 0f ff 87 9d 04 d0  |......Zj........|
00000060  ab 00 05 db 23 40 b7 3b  28 cc c0 b0 6c 0e 74 10  |....#@.;(...l.t.|
00000070

s'attend à ce que son entrée se compose d'un programme Brainfuck (en regardant uniquement les bits 0,1,4 pour distinguer entre, -. + <>] [) suivi d'un], suivi de l'entrée pour le programme Brainfuck.

Enregistrez le vidage hexadécimal ci-dessus avec xxd -r> bf.Blc

Récupérez un interpréteur blc à l’ adresse https://tromp.github.io/cl/cl.html

cc -O2 -DM=0x100000 -m32 -std=c99 uni.c -o uni
echo -n "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.]" > hw.bf
cat bf.Blc hw.bf | ./uni

Bonjour le monde!


1
Pourquoi cela existe-t-il? Apparemment, il existe même dans le domaine de la recherche . Oo
Isiah Meadows

Donc, cela ne fonctionnerait pas avec les programmes brainfuck commentés?
kamoroso94

Non, pas sans enlever les commentaires au préalable.
John Tromp

18

Retina 0.8.2 , 386 391 386 octets

Le code contient des caractères NUL ( 0x00) non imprimables . Ce n'est pas encore super golfé, parce que c'est déjà très lent, et si je joue plus, je ne sais pas combien de temps cela prendra pour finir. Apparaît pour expirer sur l'échantillon de recherche principale.

Il peut y avoir des bogues dans l'interprète en ligne ou dans mon programme (les nouvelles lignes principales n'apparaissent pas dans le résultat?).

Prend les entrées comme <code>│<input>. Non, ce n'est pas un tuyau ( |). C'est le caractère Unicode U+2502. Le code utilise également les caractères Unicode ÿ▶◀├║. Les caractères Unicode sont utilisés pour permettre la saisie de tous les caractères ASCII. Par conséquent, ces caractères doivent être séparés du code par un caractère non-ASCII.

Essayez-le en ligne

s`^.*
▶$0├║▶
s{`(▶>.*║.*)▶(.)(.?)
$1$2▶$3
▶$
▶
║▶
║▶
(▶<.*║.*)(.)▶
$1▶$2
T`ÿ-`o`(?<=▶\+.*║.*▶).
^\+

T`-ÿ`ÿo`(?<=▶-.*║.*▶).
^-

(▶\..*├.*)(║.*▶)(.)
$1$3$2$3
(▶,.*│)(.?)(.*├.*▶).
$1$3$2
▶\[(.*║.*▶)
[▶▶${1}
{`(▶▶+)([^[\]]*)\[
$2[$1▶
}`▶(▶+)([^[\]]*)\]
$2]$1
r`([[\]]*)▶\](.*║.*▶[^])
$1◀◀]$2
r{`\[([^[\]]*)(◀+)◀
$2[$1
}`\]([^[\]]*)(◀◀+)
$2◀]$1
◀
▶
}`▶([^│])(.*║)
$1▶$2
s\`.*├|║.*

Notez qu'il y a une fin de ligne à cet endroit.

Brève explication:

Les zéros 0x00sont utilisés pour la bande, qui est infinie. Le premier remplacement configure l'interprète sous la forme ▶<code>│<input>├<output>║▶<tape>, le premier étant le pointeur du code et le second le pointeur de la bande.

ÿis 0xFF(255), qui est utilisé pour la translittération (utilisée pour implémenter +et -) pour ramener les cellules à zéro.

est uniquement utilisé pour la lisibilité (dans le cas où le programme est arrêté au milieu ou si vous voulez voir le programme en cours d'exécution). Sinon, vous ne pourriez pas dire de quelle manière le pointeur se déplaçait.

Code commenté:

s`^.*                       # Initialize
▶$0├║▶
s{`(▶>.*║.*)▶(.)(.?)        # >
$1$2▶$3
▶$
▶
║▶                          # <
║▶
(▶<.*║.*)(.)▶
$1▶$2
T`ÿ-`o`(?<=▶\+.*║.*▶).      # +
^\+

T`-ÿ`ÿo`(?<=▶-.*║.*▶).      # -
^-

(▶\..*├.*)(║.*▶)(.)         # .
$1$3$2$3
(▶,.*│)(.?)(.*├.*▶).        # ,
$1$3$2
▶\[(.*║.*▶)                 # [
[▶▶${1}
{`(▶▶+)([^[\]]*)\[
$2[$1▶
}`▶(▶+)([^[\]]*)\]
$2]$1
r`([[\]]*)▶\](.*║.*▶[^])    # ]
$1◀◀]$2
r{`\[([^[\]]*)(◀+)◀
$2[$1
}`\]([^[\]]*)(◀◀+)
$2◀]$1
◀
▶
}`▶([^│])(.*║)              # next instruction
$1▶$2
s\`.*├|║.*                  # print output

Cliquez ici pour le code avec des zéros à la place des octets nuls. Les occurrences de $0ne doivent pas être remplacées par des valeurs nulles.

Edit : supporte maintenant les entrées vides et supprime les retours à la ligne.

La sortie infinie est maintenant prise en charge. (403 octets)


J'aurais bien aimé avoir placé le <code>et l'un à <tape>côté de l'autre (bien que ce soit plus de caractères) pour que la transition vers un interprète SMBF soit plus facile, si jamais je décidais de le faire.
mbomb007

14

TI-BASIC, 264 octets

En raison des limitations de TI-BASIC, cette action n’est pas prise en compte car elle enfreint la règle 2; la RAM des calculatrices est très limitée, et faire quelque chose comme 30000->dim(L1(j'utilise L1 pour la pile / matrice) va la forcer à lancer un ERR:MEMORY. En tant que tel, la pile / le tableau commence à une taille de 1 et augmente si le pointeur pointe vers un élément situé au-delà de sa fin. Il enfreint également la règle 3, car il enfreint déjà la règle 2, de sorte que je pourrais également ne pas m'embêter avec une limite de taille de cellule.

En passant, je pourrais probablement continuer à jouer au golf ... J'ai apporté une ou deux modifications à cette fin depuis la première soumission, mais si la version ci-dessous ne fonctionne pas, retournez à la modification du 6 mai 2015 et utilisez-la code à la place. De plus, comme TI-BASIC ne contient pas vraiment d’ASCII, il faut entrer des nombres de toute taille (et tout ce qui retourne un nombre, comme une variable ou une expression), puis les afficher à leur tour.

Utilisez SourceCoder pour l'intégrer dans un fichier .8xp, puis envoyez-le à votre calculatrice avec TI-Connect ou TILP ou quelque chose du genre, et exécutez-le en incluant votre programme brainfuck entre guillemets, suivis de deux points et de ce que vous avez appelé le programme TI-BASIC. Par exemple, si vous l' avez nommé Brainf, vous auriez exécuter un programme comme celui - ci: "brainfuck goes here":prgmBRAINF. Si vous avez un shell sur votre calc qui intercepte les autres commandes quand il détecte le prgmjeton, bien, faites ceci: "brainfuck goes here" -> press ENTER -> prgmBRAINF.

seq(inString("<>-+.,[]",sub(Ans,S,1)),S,1,length(Ans->L2
cumSum((Ans=7)-(Ans=8->L3
seq(Ans(X),X,dim(Ans),1,~1->L4
1->P:DelVar L11->dim(L1 //this is the same as DelVar L1:1->dim(L1 as DelVar does not require a colon or newline after its argument
For(S,1,dim(L2
L2(S->T
P-(T=1)+(T=2->P
dim(L1
Ans+(P-Ans)(P>Ans->dim(L1
L1(P)-(T=3)+(T=4->L1(P
If T=5
Disp Ans
If T=6:Then
Input V
V->L1(P
End
If T=7 and not(L1(P
S+2+sum(not(cumSum(L3(S)-1=seq(L3(X),X,S+1,dim(L3->S
1-S+dim(L3
If T=8 and L1(P
S-sum(not(cumSum(L4(Ans)=seq(L4(X),X,Ans+1,dim(L4->S
End

Si vous n'avez pas le moyen de connecter votre calculatrice à votre ordinateur et que vous voulez taper ceci sur-calc à la place (je ne vois pas pourquoi vous voudriez, mais je m'écarte du sujet), notez que ->le STO>bouton au-dessus de ON est affiché. key, ~est le symbole négatif à côté de ENTER, et pour remplacer toutes les instances de L<number>avec le jeton de liste correspondant trouvé sur2ND -> <number on keypad>

Merci à thomas-kwa (du moins, je pense que c'est son nom d'utilisateur Stack) pour m'aider à optimiser cela, en particulier avec les instructions [et ].


1
Avez-vous besoin des parens autour Ans+S?
Zacharý

@ Zacharý Bonne prise, non. Je devais avoir des doutes sur le fonctionnement de PEMDAS ou quelque chose du genre ... Je m'abstiendrai toutefois de faire des modifications, car cela fait tellement longtemps que ça ne vaut vraiment pas la peine de passer ce billet à l'avant et parce que deux octets la réduction ne va pas donner la réponse à aucun avantage sur les autres lol.
MI Wright

1
Je me souviens comme il y a deux ou trois ans lorsque j'ai utilisé ce programme pour interpréter Brainf *** sur ma calculatrice. Et, c’est une question de bon sens, je pense qu’elle devrait être au top pour être honnête.
Zacharý

1
En fait, je pense que toute cette ligne pourrait être S-sum(not(cumSum(L4(Ans)=seq(L4(X),X,Ans+1,dim(L4->S. ( a-a=0) Et hé, ne vous inquiétez pas d'oublier UN SEUL ordre d'ordre d'opération ici, j'ai vu toute une foule de gens oublier l'ordre d'opération pour %(mod) sur un défi.
Zacharý

1
Oh dang, ouais. OK, cela donne au moins 10 octets, car le if peut également être transformé en une ligne, ainsi que d’autres choses ... qui peuvent également être modifiées. Tu m'as fait fouetter ma calculatrice pour la première fois depuis un an à vérifier ce genre de choses, haha
MI Wright

13

Python 275 248 255

J'ai décidé de lui laisser une chance.

import sys
i=0
b=[0]*30000
t=''
for e in open(sys.argv[1]).read():
 t+=' '*i+['i+=1','i-=1','b[i]+=1','b[i]-=1','sys.stdout.write(chr(b[i]))','b[i]=ord(sys.stdin.read(1))','while b[i]:','pass','']['><+-.,['.find(e)]+'\n'
 i+=(92-ord(e))*(e in'][')
exec t 

12
Neat, vous générez du code source Python en utilisant brainfuck.

1
Vous pouvez supprimer 1 caractère, "importer sys en tant que" et remplacer "sys" par "s" dans le reste
VOUS, le

Notez qu'il s'agit en fait de 247 caractères. (Voir l'espace méchant après exec t?). Si vous utilisez le conseil de S.Mark et créez également le forcycle complet en une seule ligne, vous pouvez le réduire à 243 caractères.
Oleh Prypin le

Cela échoue sur toute entrée contenant []un programme bf valide bien que trivial. J'ai suggéré une modification qui corrige cela, mais augmente le nombre de caractères. Pour réduire davantage le nombre de caractères, vous pouvez from sys import *et utiliser à la 'i+=1,...'.split(',')place de ['i+=1',...].
Boothby

7
Je le ferais +1, mais de nombreuses améliorations ont été suggérées et non mises en œuvre.
mbomb007

12

Haskell, 457 413 caractères

import IO
import System
z=return
'>'#(c,(l,d:r))=z(d,(c:l,r))
'<'#(d,(c:l,r))=z(c,(l,d:r))
'+'#(c,m)=z(succ c,m)
'-'#(c,m)=z(pred c,m)
'.'#t@(c,_)=putChar c>>hFlush stdout>>z t
','#(_,m)=getChar>>=(\c->z(c,m))
_#t=z t
_%t@('\0',_)=z t
i%t=i t>>=(i%)
b('[':r)=k$b r
b(']':r)=(z,r)
b(c:r)=f(c#)$b r
b[]=(z,[])
f j(i,r)=(\t->j t>>=i,r)
k(i,r)=f(i%)$b r
main=getArgs>>=readFile.head>>=($('\0',("",repeat '\0'))).fst.b

Ce code "compile" le programme BF en une IOaction de la forme suivante: State -> IO Statel'état est une fermeture à glissière sur une chaîne infinie.

Triste d'avoir dû dépenser 29 caractères pour désactiver la mise en mémoire tampon. Sans cela, cela fonctionne, mais vous ne voyez pas les invites avant de devoir saisir une entrée. Le compilateur lui-même ( b, fet k) ne comporte que 99 caractères, le temps d'exécution ( #et %) 216. Le pilote a l'état initial de 32 autres.

>ghc -O3 --make BF.hs 
[1 of 1] Compiling Main             ( BF.hs, BF.o )
Linking BF ...

>./BF HELLO.BF 
Hello World!

>./BF PRIME.BF 
Primes up to: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 

Mise à jour du 15/02/2011: Suggestions de JB Incorporated, modification du nom et renforcement du nommain


1
Vous devriez pouvoir obtenir la mise en mémoire tampon de just IO, et les arguments de just System(-19). Le problème de mise en mémoire tampon me préoccupe également, car la spécification ne le mentionne pas vraiment et la réponse la plus votée ne fait même pas d'E / S. Si vous devez le conserver, il est probablement plus court hFlushaprès chaque écriture que de changer le mode de mise en mémoire tampon global (-34 + 15).
JB

11

Convoyeur, 953

C'est peut-être le plus beau code que vous verrez jamais:

0

:I\1\@p
>#====)
^#====<
PP0
P<=======================<
00t:)01t1  a:P:P:P:P:P:P:^
>===========">">2>">2>">"^
^           +^-^5^ ^5^]^.^
^           "^"^*^"^*^"^"^
^           -^-^6^-^6^-^-^
^           #^#^*^#^*^#^#^
^           P P -^P )^P P
^           P P #^P )^P P
^t1\)t0:))t01   P   -^  1
^===========<   P   #^  0
^  t1\(t0:))t01     P   t
^=============<     P   )
^         t11(t01   0 0 )
^===============<. t P 10
^                 FT#T#=<
^=================< P 
^             t11)t01 
^===================< 10t))0tP00t:(01t(1a:P:
^                     >=====#=>==========">"
^                             ^          ]^[
^                           P ^          "^"
^===========================<=^#=====<   -^-
                            ^==<     ^ PP#^#=
                                     ^===PTPT<
                                     ^  )P P
                                     ^=<=< (
                                       ^===<

8
Pourriez-vous ajouter une explication et un lien vers une implémentation? Je veux comprendre la beauté. ;)
DLosc

1
Eh bien, je suis en train de le développer, il existe un compilateur et une très mauvaise explication sur github.com/loovjo/Conveyor . La source est assez lisible si vous voulez la comprendre.
Loovjo

9

C 284 362 (à partir d'un fichier)

#include <stdio.h>
char b[30000],z[9999],*p=b,c,*a,i;f(char*r,int s){while(c=*a++){if(!s){(c-62)?(c-60)?(c-43)?(c-45)?(c-46)?(c-44)?0:(*p=getchar()):putchar(*p):--*p:++*p:--p:++p;if(c==91)f(a,!*p);else if(c==93){if(!*p)return;else a=r;}}else{if(c==93){--s;if(!*p&&!s)return;}else if(c==91){s++;}}}}main(int c,char**v){fread(z,1,9999,fopen(*++v,"r"));a=z;f(0,0);}

Primes:

Primes jusqu’à: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 73 79 83 89 97
Appuyez sur n'importe quelle touche pour continuer . . .

Compilé et exécuté avec succès VS2008

La solution d'origine n'a pas réussi à reconnaître les boucles initialement définies à zéro. Encore de la place pour jouer au golf. Mais finalement, résout le programme Prime Number.

Ungolfed:

#include <stdio.h>
char b[30000],z[9999],*p=b,c,*a,i;
f(char*r,int s)
{
    while(c=*a++)
    {   
        if(!s)
        {
            (c-62)?(c-60)?(c-43)?(c-45)?(c-46)?(c-44)?0:(*p=getchar()):putchar(*p):--*p:++*p:--p:++p;
            if(c==91)f(a,!*p);
            else if(c==93){if(!*p)return;else a=r;}
        }
        else
        {
            if(c==93)
            {
                --s;
                if(!*p&&!s)return;
            }
            else if(c==91)
            {
                s++;
            }
        }
    }
}

main(int c,char**v){
    fread(z,1,9999,fopen(*++v,"r"));
    a=z;
    f(0,0);
}

Tests:

Bonjour le monde

Rot13


Vérifiez-vous le même pointeur ( l) à chaque boucle? Je pense que vous êtes censé vérifier l'emplacement actuel de la tête ( p).
Alexandru

Je passe le pointeur au tampon et le pointeur au flux. Il vérifie à la fin de la boucle si le pointeur ldans la mémoire tampon a atteint zéro et casse sinon il réinitialise le flux à la boucle d'origine [. Ceci est nécessaire pour les [boucles imbriquées .
snmcdonald

1
Ouais. J'ai pensé ainsi. Vous ne devez pas vérifier la valeur au pointeur lors de la première entrée dans la boucle, mais la valeur au pointeur actuel. Vérifiez le test dans la question. Votre programme se bloque.
Alexandru

1
Vous pouvez remplacer break;elsepar return;.
Alexandru

3
Je pense que vous pouvez remplacer (c==62)?a:bpar (c-62)?b:a.
Alexandru

9

PHP 5.4, 296 294 273 263 261 209 191 183 178 166 caractères:

Je lui ai donné un coup de feu sans utiliser eval, mais j'ai finalement dû l'utiliser

<?$b=0;eval(strtr(`cat $argv[1]`,["]"=>'}',"["=>'while($$b){',"."=>'echo chr($$b);',","=>'$$b=fgetc(STDIN);',"+"=>'$$b++;',"-"=>'$$b--;',">"=>'$b++;',"<"=>'$b--;']));

Toutes les commandes fonctionnent. Cela abuse fortement des variables variables et génère des avertissements. Cependant, si l'on modifie leur php.ini en avertissements de blocage (ou en stderr vers / dev / null), cela fonctionnera très bien.

Vérification (c'est l'exemple "Hello World!" De Wikipedia ): http://codepad.viper-7.com/O9lYjl

Ungolfed, 367 365 335 296 267 caractères:

<?php
$a[] = $b = 0;
$p = implode("",file($argv[1])); // Shorter than file_get_contents by one char
$m = array("]" => '}', "[" => 'while($a[$b]){',"." => 'echo chr($a[$b]);', "," => '$a[$b]=fgetc(STDIN);', "+" => '$a[$b]++;', "-" => '$a[$b]--;', ">" => '$b++;', "<" => '$b--;');
$p = strtr($p,$m);
@eval($p);

Cela devrait être exécuté via la ligne de commande: php bf.php hello.bf


8

Windows PowerShell, 204

'$c=,0*3e4;'+@{62='$i++
';60='$i--
';43='$c[$i]++
';45='$c[$i]--
';44='$c[$i]=+[console]::ReadKey().keychar
';46='write-host -n([char]$c[$i])
';91='for(;$c[$i]){';93='}'}[[int[]][char[]]"$(gc $args)"]|iex

Conversion assez simple des instructions, puis Invoke-Expression.

Histoire:

  • 2011-02-13 22:24 (220) Première tentative.
  • 2011-02-13 22:25 (218) 3e4est plus court que 30000.
  • 2011-02-13 22:28 (216) Des sauts de ligne inutiles. La correspondance sur des entiers au lieu de caractères est plus courte.
  • 2011-02-13 22:34 (207) Index utilisés dans une table de hachage au lieu de switch.
  • 2011-02-13 22:40 (205) Une meilleure conversion en chaîne supprime deux parenthèses.
  • 2011-02-13 22:42 (204) Plus besoin d'espace après l'argument Write-Host.

8

C, 333 caractères

Ceci est mon premier interprète BF et le premier golf que j'ai réellement dû déboguer.

Ceci exécute le générateur de nombres premiers sur Mac OS X / GCC, mais un supplément #include<string.h>peut être nécessaire pour un coût de 19 caractères supplémentaires si la définition implicite de strchrne fonctionne pas sur une autre plate-forme. En outre, cela suppose O_RDONLY == 0. En dehors de cela, laisser de intcôté la déclaration de Msauvegarde sauve 3 caractères mais cela ne semble pas être conforme à C99. Même avec le troisième *dans b().

Cela dépend des particularités du codage ASCII. Les opérateurs Brainfuck sont tous des paires complémentaires séparées par une distance de 2 dans l'espace de code ASCII. Chaque fonction de ce programme implémente une paire d'opérateurs.

#include<unistd.h>
char C[30000],*c=C,o,P[9000],*p=P,*S[9999],**s=S,*O="=,-\\",*t;
m(){c+=o;}
i(){*c-=o;}
w(){o<0?*c=getchar():putchar(*c);}
b(){if(o>0)*c?p=*s:*--s;else if(*c)*++s=p;else while(*p++!=93)*p==91&&b();}
int(*M[])()={m,i,w,b};
main(int N,char**V){
read(open(V[1],0),P,9e3);
while(o=*p++)
if(t=strchr(O,++o&~2))
o-=*t+1,
M[t-O]();
}

Je pense que vous pouvez le réduire davantage en utilisant la notation "e" pour tous les gros nombres.
luser droog

@ utilisateur: Au début, j'ai aussi été surpris, mais le langage et le compilateur ne le permettent pas. J'ai réussi à réduire encore 4 caractères avec des ajustements, et utiliser une #definetable à la place de la table de fonctions serait probablement aussi un testeur. J'aime juste le nombre 333 et le tableau: v).
Potatoswatter

Oh, c'est vrai. J'aurais vraiment dû savoir ça. La notation E est dans la production pour une constante à virgule flottante, alors qu'une déclaration nécessite un entier. BTW, cela peut être tricher, mais consultez nieko.net/projects/brainfuck pour la version de Urban Müller. Le plus gros gain semble être un usage intensif de ||.
luser droog

8

CJam, 75 octets

lq3e4Vc*@{"-<[],.+>"#"T1$T=(t T(:T; { _T=}g \0+(@T@t _T=o "_'(')er+S/=}%s~@

Essayez-le en ligne: inverseur de chaîne , Hello World .

Explication

Prend le code sur la première ligne de STDIN et l'insère sur toutes les lignes en dessous.

l            Read a line from STDIN (the program) and push it.
 q           Read the rest of STDIN (the input) and push it.
  3e4Vc*     Push a list of 30000 '\0' characters.
        @    Rotate the stack so the program is on top.

{               }%   Apply this to each character in prog:
 "-<[],.+>"#         Map '-' to 0, '<' to 1, ... and everything else to -1.
            ...=     Push a magical list and index from it.

s~       Concatenate the results and evaluate the resulting string as CJam code.
  @      Rotate the top three elements again -- but there are only two, so the
         program terminates.

Qu'en est-il de cette liste magique?

"T1$T=(t T(:T; { _T=}g \0+(@T@t _T=o "  Space-separated CJam snippets.
                                        (Note the final space! We want an empty
                                        string at the end of the list.)
_'(')er+                                Duplicate, change (s to )s, append.
        S/                              Split over spaces.

La liste résultante est la suivante:

T1$T=(t    (-)
T(:T;      (<)
{          ([)
_T=}g      (])
\0+(@T@t   (,)
_T=o       (.)
T1$T=)t    (+)
T):T;      (>)
{          (unused)
_T=}g      (unused)
\0+(@T@t   (unused)
_T=o       (unused)
           (all other characters)

Nous générons les extraits pour +et >de ceux pour -et <, simplement en remplaçant les parenthèses de gauche («décrémentation» de CJam) par des parenthèses droites («incrémentation» de CJam).


La réponse la plus courte et le plus grand gagnant
Jack Giffin

7

F #: 489 caractères

Le programme suivant ne saute pas aux instructions '[' / ']', mais scanne le code source pour le prochain jeton correspondant. Bien sûr, cela le ralentit un peu, mais il peut toujours trouver les nombres premiers inférieurs à 100. Les types entiers F # ne débordent pas, mais sont bouclés.

Voici la version courte:

[<EntryPoint>]
let M a=
 let A,B,i,p,w=Array.create 30000 0uy,[|yield!System.IO.File.ReadAllText a.[0]|],ref 0,ref 0,char>>printf"%c"
 let rec g n c f a b=if c then f i;if B.[!i]=a then g(n+1)c f a b elif B.[!i]=b then(if n>0 then g(n-1)c f a b)else g n c f a b
 while !i<B.Length do(let x=A.[!p]in match B.[!i]with|'>'->incr p|'<'->decr p|'+'->A.[!p]<-x+1uy|'-'->A.[!p]<-x-1uy|'.'->w x|','->A.[!p]<-byte<|stdin.Read()|'['->g 0(x=0uy)incr '['']'|']'->g 0(x>0uy)decr ']''['|_->());incr i
 0

Un méchant piège était que le programme primes.bf s'étouffait avec les nouvelles lignes de Windows. Afin de l'exécuter, je devais enregistrer le numéro d'entrée dans un document texte au format UNIX et l'envoyer au programme avec un tuyau:

interpret.exe prime.bf < number.txt

Edit: entrer Alt + 010 suivi de Enter fonctionne également dans Windows cmd.exe

Voici la version la plus longue:

[<EntryPoint>]
let Main args =
    let memory = Array.create 30000 0uy
    let source = [| yield! System.IO.File.ReadAllText args.[0] |]
    let memoryPointer = ref 0
    let sourcePointer = ref 0
    let outputByte b = printf "%c" (char b)
    let rec scan numBraces mustScan adjustFunc pushToken popToken =
        if mustScan then
            adjustFunc sourcePointer
            if source.[!sourcePointer] = pushToken then
                scan (numBraces + 1) mustScan adjustFunc pushToken popToken
            elif source.[!sourcePointer] = popToken then
                if numBraces > 0 then scan (numBraces - 1) mustScan adjustFunc pushToken popToken
            else
                scan numBraces mustScan adjustFunc pushToken popToken 

    while !sourcePointer < source.Length do
        let currentValue = memory.[!memoryPointer]
        match source.[!sourcePointer] with
            | '>' -> incr memoryPointer
            | '<' -> decr memoryPointer
            | '+' -> memory.[!memoryPointer] <- currentValue + 1uy
            | '-' -> memory.[!memoryPointer] <- currentValue - 1uy
            | '.' -> outputByte currentValue
            | ',' -> memory.[!memoryPointer] <- byte <| stdin.Read()
            | '[' -> scan 0 (currentValue = 0uy) incr '[' ']'
            | ']' -> scan 0 (currentValue > 0uy) decr ']' '['
            |  _  -> ()
        incr sourcePointer
    0 

J'ai résolu le problème Enter en ne le pressant pas mais en appuyant sur Ctrl + J :-)
Joey

Ctrl + J n'a pas fonctionné pour moi, mais entrer Alt + 010 suivi de Entrée a fonctionné.
cfern le

7

Delphi, 397 382 378 371 366 364 328 caractères

Mange ce Delphi!

328 var p,d:PByte;f:File;z:Word=30000;x:Int8;begin p:=AllocMem(z+z);d:=p+z;Assign(F,ParamStr(1));Reset(F,1);BlockRead(F,p^,z);repeat z:=1;x:=p^;case x-43of 1:Read(PChar(d)^);3:Write(Char(d^));0,2:d^:=d^+44-x;17,19:d:=d+x-61;48,50:if(d^=0)=(x=91)then repeat p:=p+92-x;z:=z+Ord(p^=x)-Ord(p^=x xor 6);until z=0;end;Inc(p)until x=0;end.

Voici le même code, mis en retrait et commenté:

var
  d,p:PByte;
  x:Int8;
  f:File;
  z:Word=30000;
begin
  // Allocate 30000 bytes for the program and the same amount for the data :
  p:=AllocMem(z+z);
  d:=p+z;
  // Read the file (which path must be specified on the command line) :
  Assign(F,ParamStr(1));
  Reset(F,1);
  BlockRead(F,p^,z);
  // Handle all input, terminating at #0 (better than the spec requires) :
  repeat
    // Prevent a begin+end block by preparing beforehand (values are only usable in '[' and ']' cases) :
    z:=1;                       // Start stack at 1
    x:=p^;                      // Starting at '[' or ']'
    // Choose a handler for this token (the offset saves 1 character in later use) :
    case x-43of
      1:Read(PChar(d)^);        // ','     : Read 1 character from input into data-pointer
      3:Write(Char(d^));        // '.'     : Write 1 character from data-pointer to output
      0,2:d^:=d^+44-x;          // '+','-' : Increase or decrease data
      17,19:d:=d+x-61;          // '<','>' : Increase or decrease data pointer
      48,50:                    // '[',']' : Start or end program block, the most complex part :
        if(d^=0)=(x=91)then     // When (data = 0 and forward), or when (data <> 0 and backward)
        repeat                  //
          p:=p+92-x;            // Step program 1 byte back or forward
          z:=z+Ord(p^=x)        // Increase stack counter when at another bracket
              -Ord(p^=x xor 6); // Decrease stack counter when at the mirror char
        until z=0;              // Stop when stack reaches 0
    end;
    Inc(p)
  until x=0;
end.

Celui-ci m'a pris quelques heures, car ce n'est pas le genre de code que j'écris normalement, mais profitez-en!

Remarque: le test principal fonctionne, mais ne s'arrête pas à 100, car il indique # 13 (CR) avant # 10 (LF) ... est-ce que d'autres soumissions souffrent également de ce problème lorsqu'elles sont exécutées sur des systèmes d'exploitation CRLF?


Hou la la! Je n'aurais jamais imaginé l'emporter sur la concision de C avec Delphi! Pas avant d'avoir appliqué mes idées à CI devine ;-)
PatrickvL Le

7

C, 260 + 23 = 283 octets

J'ai créé un programme C qui peut être trouvé ici .

main(int a,char*s[]){int b[atoi(s[2])],*z=b,p;char*c=s[1],v,w;while(p=1,
*c){q('>',++z)q('<',--z)q('+',++*z)q('-',--*z)q('.',putchar(*z))q(',',*z
=getchar())if(*c=='['||*c==']'){v=*c,w=184-v;if(v<w?*z==0:*z!=0)while(p)
v<w?c++:c--,p+=*c==v?1:*c==w?-1:0;}c++;}}

Il doit être compilé via gcc -D"q(a,b)"="*c-a||(b);" -o pmmbf pmmbf.cet peut être appelé comme suit: pmmbf ",[.-]" 30000le premier argument (entre guillemets) contenant le programme bf à exécuter, le deuxième déterminant la taille de la bande.


1
Je pense que vous devez ajouter 23 caractères à votre compte pour cette -D"q(a,b)"="*c-a||(b);"option, car cela semble (pour ma compréhension limitée, au moins) vous aider à réduire votre code.
Gareth

L'option est incluse dans le texte posté. La raison en est d’éviter les mots definetrop longs et les nouvelles lignes, mais je ne pense pas que ce soit vraiment casher. Quoi qu'il en soit, avec les citations, commentez, et gcc -Dje ne vois pas l'avantage du tout.
Potatoswatter

5

C, 267

#define J break;case
char*p,a[40000],*q=a;w(n){for(;*q-93;q++){if(n)switch(*q){J'>':++p;J'<':--p;J'+':++*p;J'-':--*p;J'.':putchar(*p);J',':*p=getchar();}if(*q==91){char*r=*p&&n?q-1:0;q++;w(r);q=r?r:q;}}}main(int n,char**v){p=a+read(open(v[1],0),a,9999);*p++=93;w(1);}

Exécuter en tant que ./a.out primes.bf

Version non-golfée:

#define J break;case

char*p,a[40000],*q=a; // packed so program immediately followed by data

w(n){
    for(;*q-93;q++){ // until ']'
        if(n)switch(*q){ // n = flagged whether loop evaluate or skip(0)
                J'>':++p;
                J'<':--p;
                J'+':++*p;
                J'-':--*p;
                J'.':putchar(*p);
                J',':*p=getchar();
        }
        if(*q==91){char*r=*p&&n?q-1:0;q++;w(r);q=r?r:q;} // recurse on '[', record loop start
    }
}

main(int n,char**v){
    p=a+read(open(v[1],0),a,9999);
    *p++=93; // mark EOF with extra ']' and set data pointer to next
    w(1); // begin as a loop evaluate
}

5

Python 2, 223

J'avoue avoir recyclé un de mes anciens programmes (mais j'ai dû le modifier un peu, car l'ancienne version n'avait pas d'entrée, mais une vérification d'erreur ...).

P="";i,a=0,[0]*30000
import os,sys
for c in open(sys.argv[1]).read():x="><+-.[,]".find(c);P+=" "*i+"i+=1 i-=1 a[i]+=1 a[i]-=1 os.write(1,chr(a[i])) while+a[i]: a[i]=ord(os.read(0,1)) 0".split()[x]+"\n";i+=(x>4)*(6-x)
exec P

Lance bien la calculatrice de nombres premiers.

Je vois maintenant qu'Alexandru a une réponse qui présente certaines similitudes. Je posterai tout de même ma réponse car je pense qu’elle contient de nouvelles idées.


5

C (gcc) Linux x86_64, 884 621 525 487 439 383 358 354 octets

*z,*mmap();d[7500];(*p)();*j(a,g)char*a;{char*t=a,*n,c,q=0;for(;read(g,&c,!q);)t=c==91?n=j(t+9,g),z=mempcpy(t,L"\xf003e80Ƅ",5),*z=n-t-9,n:c==93?q=*t++=233,z=t,*z=a-13-t,z+1:stpcpy(t,c-62?c-60?c-43?c-45?c-46?c-44?"":"1\xc0P_\xF\5":"RXR_\xF\5":L"໾":L"۾":L"컿":L"웿");return t;}main(P,g)int**g;{p=mmap(0,1<<20,6,34,0,0);p(*j(p,open(g[1],0))=195,d,1);}

Essayez-le en ligne!

Il s'agit d'un JIT qui compile le code BF en langage machine x86_64 au moment de l'exécution. Ceci effectue une traduction directe si souvent des séquences se produisant telles que >>>, <<<, +++et ---ne sont pas fusionnés en des instructions plus rapides.

Version moins golfée:

// size of data area
*z,c,*mmap();d[7500];(*p)();
// recursive function translates BF commands to x86_64 instructions
*j(a,g)char*a;{
  char*t=a,*n,q=0;
  for(;read(g,&c,!q);)
    t=c==91? // [
        // cmpb $0x0,(%rsi)
        // je n-t-9
        n=j(t+9,g),
        z=mempcpy(t,L"\xf003e80Ƅ",5)
        *z=n-t-9,
        n
      :
        c==93? // ]
          // jmp a-13-t
          q=*t++=233,
          z=t,
          *z=a-13-t,
          z+1
        :
          stpcpy(t,c-62? // >
                     c-60? // <
                       c-43? // +
                         c-45? // -
                           c-46? // .
                             c-44? // ,
                               ""
                             :
                               // xor %eax,%eax
                               // push %rax
                               // pop %rdi
                               // syscall
                               "1\xc0P_\xF\5"
                           :
                             // push %rdx
                             // pop %rax
                             // push %rdx
                             // pop %rdi
                             // syscall
                             "RXR_\xF\5"
                         :
                           // decb (%rsi)
                           L"໾"
                       :
                         // incb (%rsi)
                         L"۾"
                     :
                       // dec %esi
                       L"컿"
                   :
                     // inc %esi
                     L"웿");
  return t;
}
main(P,g)int**g;{
  // allocate text (executable) memory and mark as executable
  p=mmap(0,1<<20,6,34,0,0);
  // run JIT, set %rdx=1 and call code like a function
  p(*j(p,open(g[1],0))=195,d,1);
}

4

C, 374 368

Lit à partir d'un fichier. Passe le test PRIME.BF.

Utilisation: ./a.out PRIME.BF

#include <stdio.h>
main(int c,char**v){int m[30000],s[99],p=0,i=0,n=0;char l[9999],d;FILE*f=fopen(v[1],"r");for(l[i]=0;i<9999&&l[i]!=EOF;l[i]=getc(f))i++;for(i=1;d=l[i];i++){if(!n){p+=d-62?0:1;p-=d-60?0:1;m[p]+=d-43?0:1;m[p]-=d-45?0:1;if(d==46)putchar(m[p]);if(d==44){m[p]=getchar();}if(d==93){i=s[c]-1;c--;n++;}}if(d==91){if(m[p]){c++;s[c]=i;}else{n++;}}n-=d-93?0:1;}}


Reformaté:

#include <stdio.h>
main(int c,char**v){
    int m[3000],s[99],p=0,i=0,n=0;
    char l[9999],d;
    FILE*f=fopen(v[1],"r");
    for(l[i]=0;i<9999&&l[i]!=EOF;l[i]=getc(f))i++;
    for(i=1;d=l[i];i++){
        if(!n){ // > < + - . , ] \n [ ]
            p+=d-62?0:1;
            p-=d-60?0:1;
            m[p]+=d-43?0:1;
            m[p]-=d-45?0:1;
            if(d==46)putchar(m[p]);
            if(d==44){m[p]=getchar();}
            if(d==93){i=s[c]-1;c--;n++;}
        }
        if(d==91){if(m[p]){c++;s[c]=i;}else{n++;}}
        n-=d-93?0:1;
    }
}

3000 vs 30000. Votre tampon est trop petit. La taille du programme est trop petite aussi.
Alexandru

J'ai fait une faute de frappe, corrigé. Qu'entendez-vous par taille du programme? Si vous voulez parler de la taille maximale du fichier, vous n'avez pas spécifié le minimum qu'il devrait gérer.
Jtjacques

4

Lua, 285

loadstring("m,p={0},1 "..io.open(arg[1]):read"*a":gsub("[^.,<>[%]+-]",""):gsub(".",{["."]="io.write(string.char(@)) ",[","]="@=io.read(1):byte() ",["<"]="p=p-1 ",[">"]="p=p+1 @=@or 0 ",["["]="while @~=0 do ",["]"]="end ",["+"]="@=(@+1)%256 ",["-"]="@=(@-1)%256 "}):gsub("@","m[p]"))()

Version assez lisible:

loadstring( --execute
    "m,p={0},1 ".. --initialize memory and pointer
    io.open(arg[1]) --open file
        :read"*a" --read all
            :gsub("[^.,<>[%]+-]","") --strip non-brainfuck
                :gsub(".", --for each character left
                    {["."]="io.write(string.char(@)) ", -- '@' is shortcut for 'm[p]', see below
                    [","]="@=io.read(1):byte() ",
                    ["<"]="p=p-1 ",
                    [">"]="p=p+1 @=@or 0 ", --if a before unexplored memory cell, set to 0
                    ["["]="while @~=0 do ",
                    ["]"]="end ",
                    ["+"]="@=(@+1)%256 ", --i like it overflowing
                    ["-"]="@=(@-1)%256 "
                    }
                )
                    :gsub("@","m[p]") --replace the '@' shortcut
    ) --loadstring returns a function
() --call it

Fonctionne parfaitement

Lua, 478, sans corde de charge

local m,p,i,r,c={0},1,1,{},io.open(arg[1]):read"*a"while i<=#c do(({[43]=function()m[p]=(m[p]+1)%256 end,[45]=function()m[p]=(m[p]-1)%256 end,[62]=function()p=p+1 m[p]=m[p]or 0 end,[60]=function()p=p-1 end,[46]=function()io.write(string.char(m[p]))end,[44]=function()m[p]=io.read(1):byte()end,[91]=function()if m[p]==0 then i=select(2,c:find("%b[]",i))else r[#r+1]=i end end,[93]=function()if m[p]==0 then r[#r]=nil else i=r[#r] end end})[c:byte(i)]or function()end)()i=i+1 end

Version lisible:

local m,   p, i, r,  c= --memory, pointer, brackets stack, code
      {0}, 1, 1, {}, io.open(arg[1]) --open file
              :read"*a" --read it
while i<=#c do --while there's code
    (
        (
            {
                [43]=function() -- +
                    m[p]=(m[p]+1)%256
                end,
                [45]=function() -- -
                    m[p]=(m[p]-1)%256
                end,
                [62]=function() -- >
                    p=p+1 m[p]=m[p]or 0 --if new memory cell, set it to 0
                end,
                [60]=function() -- <
                    p=p-1
                end,
                [46]=function() -- .
                    io.write(string.char(m[p]))
                end,
                [44]=function() -- ,
                    m[p]=io.read(1):byte()
                end,
                [91]=function() -- [
                    if m[p]==0 then
                        i=select(2,c:find("%b[]",i)) --find matching ]
                    else
                        r[#r+1]=i --push position to the stack
                    end
                end,
                [93]=function() -- ]
                    if m[p]==0 then
                        r[#r]=nil --pop from stack
                    else
                        i=r[#r] --go to position on the top of stack
                    end
                end
            }
        )[c:byte(i)] --transform character into code
        or function()end --do nothing on non-brainfuck
    )() --run the resulting function
    i=i+1 --go to the next opcode
end

4

Brainfuck, 948 octets

Eh bien, cela a pris un certain temps. J'ai joué au golf avec un auto-interprète Brainfuck en… pas moi.

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

4

Rappel , 594 octets

En bref: Recall n’a pas d’opérateurs arithmétiques au sens classique, il n’a que des opérations au niveau des bits. Vous ne pouvez pas simplement "ajouter un", etc. Rappel est également strictement basée sur la pile.

DC505M22022M32032M606M42042M707M92092M4405022o032o06o042o07o092o044o1305022o06o042o092o52052q.q2305022o06o07o93093q.q5403206o07o14014q.q6403206o042o07o24024q.q74Yx34034z03MMMMMMMM034o3yY030401r3.4.101zyY040301r4.3.101zY01052gZ02Z040301052023s4.3.10zyY01023gZ02z030401023052s3.4.10zyY01093gZ02q20zyY01054gZ02u20zyY01014gZx20zyY01064gZ02X0zyY01024gZ03304302r33.43.20zyY01074gZ04303302r43.33.20zyyQ6205.8Y06208g6206208iZ08M808013izy062U7205.9Y07209g7207209iz09M909013izy072R53.63.82063MMMMMMMM053o63082013i53082KKKKKKKK82053063082S84.94.12.73.83t012073083TY083073012r83.73.12012084gzY012094gZt0zyy

Exemple 1: imprimer quelque chose

Contribution:

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

Sortie:

PPCG rocks!

Exemple 2: indiquez 100 nombres carrés en sortie

Contribution:

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

Sortie:

0
1
4
9
16
25
36
49
64
81
100

Cet exemple peut prendre quelques minutes pour s'exécuter et provoquer un message "cet onglet est gelé". Ignorez ça et attendez.


4
Le domaine de votre site Web a expiré. En outre, cette réponse est sans concurrence, car le langage est plus récent que le défi.
mbomb007

3

OCaml (lex), 497 caractères

OCamllex fait partie de la distribution standard d’OCaml.

{let a=Array.create 30000 0
let(%)f g h=f(g h)
let s v i=a.(i)<-v;i
let o d i=s(a.(i)+d)i
let p i=print_char(Char.chr a.(i));flush stdout;i
let r i=s(Char.code(input_char stdin))i
let rec w g i=if 0=a.(i)then i else w g(g i)
let n x=x}
rule t f=parse
|'>'{t(succ%f)lexbuf}
|'<'{t(pred%f)lexbuf}
|'+'{t((o 1)%f)lexbuf}
|'-'{t((o(-1))%f)lexbuf}
|'.'{t(p%f)lexbuf}
|','{t(r%f)lexbuf}
|'['{t((w(t n lexbuf))%f)lexbuf}
|']'|eof{f}
|_{t f lexbuf}
{let _=t n(Lexing.from_channel(open_in Sys.argv.(1)))0}

Enregistrer sous b.mll et exécuter avec

ocamllex b.mll && ocaml b.ml prime.bf

Je n'aime pas analyser manuellement, alors j'ai utilisé le générateur de lexer fourni. À partir des jetons lus, nous composons une fonction pour tout le programme brainf * ck.


3

C # (2861 caractères, ~ 84 lignes)

Ce n'est pas la plus jolie solution au problème, et probablement pas tout ce que «Golf-ish», puisque je n'étais pas aussi préoccupé par la longueur que j'aurais probablement dû l'être. (Je n'ai pas supprimé les commentaires ni les espaces.) Je voulais juste essayer quelque chose dans une nouvelle langue, pour voir si je pouvais. Si je le faisais à nouveau, j'abandonnerais l'utilisation de la pile pour revenir de ']' et regarderais en arrière. Exécutée sans arguments de ligne de commande, elle exécute le programme hello world donné dans la description du problème. Il accepte un argument de ligne de commande, le nom du fichier du programme à exécuter.

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            String ProgSource;
            if (args.Length > 0)
                ProgSource = System.IO.File.ReadAllText(args[0]);
            else //hello world
                ProgSource = "";

            Stack<int> stack = new Stack<int>();
            char[] bfProg = ProgSource.ToCharArray();
            char[] mem = new char[30000];
            int ptr = 0;

            for (int ip = 0; ip<bfProg.Length; ip++){
                switch (bfProg[ip])
                {
                    case ('>'): ptr++;  break;
                    case ('<'): ptr--;  break;
                    case ('+'): mem[ptr]++; break;
                    case ('-'): mem[ptr]--; break;
                    case ('.'): Console.Write(mem[ptr]); break;
                    case (','): 
                        char key = Console.ReadKey(false).KeyChar;
                        if (key == '\r')
                        {
                            key = (char)10;
                            Console.WriteLine();
                        }
                        mem[ptr] = key;
                        break;
                    case ('['):
                        if (mem[ptr] == 0)
                        {
                            int openBraces = 1;
                            //find the closing brace for this expression
                            for (int x = 1; x < (bfProg.Length - ip); x++)
                            {
                                if (bfProg[ip + x] == ']') openBraces--;
                                if (bfProg[ip + x] == '[') openBraces++;
                                if (openBraces == 0)
                                {
                                    if (stack.Peek() == ip) stack.Pop();
                                    ip += x;
                                    break;
                                }                                
                            }
                       }
                       else
                       {
                           stack.Push(ip);
                       }
                       break;
                    case (']'):
                        if (mem[ptr] == 0)
                            stack.Pop();
                        else
                        {
                            ip = stack.Peek();
                        }
                        break;
                }
            }

            Console.WriteLine("\n\n\nExecution Completed Sucessfully. Press any key to continue...");
            Console.ReadKey();

        }
    }

}

Edit: Suppression des références inutilisées.


1
@ mbomb007 - Mise à jour. Complètement oublié j'ai même fait celui-ci. (Je ne savais même pas que quelqu'un lisait ces vieilles questions)
theB

Non seulement les gens les lisent toujours, mais ils répondent toujours et les jouent au golf.
mbomb007

3

C (gcc) , 273 268 octets

main(_,a){_=fopen("w.c","w");fputs("main(){char a[30000],*p=a;",_);x:a=getchar();fputs(a-62?a-60?a-43?a-45?a-46?a-44?a-91?a-93?~a?"":"}":"}":"while(*p){":"*p=getchar();":"putchar(*p);":"--*p;":"++*p;":"--p;":"++p;",_);if(~a)goto x;fclose(_);system("cc w.c;./a.out");};

Essayez-le en ligne!

-5 grâce à ceilingcat

Prend la contribution de stdin.

Cela dépend un peu de l'environnement, mais est assez cohérent. C’est effectivement la solution eval pour c. Il écrit un programme C approprié dans le fichier wc, le compile et l'exécute comme l'exécutable souhaité. Ainsi, en tant qu'effet bonus, le code bf est compilé et laissé a.outcomme binaire. Notez que selon le système, vous devrez peut-être modifier la dernière chaîne. En particulier, la plupart des compilateurs Windows c appellent l'exécutable par défaut "a.exe". Heureusement, autant que je sache, ils ont tous la même longueur, donc le décompte est identique. (Cependant, si vous n'avez pas défini de cc, vous devrez peut-être ajouter une lettre telle que gcc à la commande de compilation en ajoutant 1 octet).

Je suis conscient que ce fil est un peu vieux, mais je n'ai pas encore vu ce style de solution C, alors j'ai pensé l'ajouter.



2

[MODIFIER]

C ++ 11, 355, lit à partir du fichier:

#include<functional>
#include<stdio.h>
main(){
char b[30000],g[9999],*f=g,*p=b,n[]="+-,.><[]",j;
std::function<void()>m[]={
[&p]{(*p)++;},
[&p]{(*p)--;},
[&p]{*p=getchar();},
[&p]{putchar(*p);},
[&p]{p++;},
[&p]{p--;},
[&p,&f]{if(!(*p))while(*f-93)f++;},
[&f,&m]{while(*f-91)f--;m[6]();}
};
fread(g,1,9999,fopen(a[1],0));
for(;*f;f++)for(j=0;n[j];j++)if(n[j]==*f)m[j]();
}

Tester

http://ideone.com/b7vO4

[ANCIENNE VERSION]

C ++ 11, 391, à voir en cours d'exécution: http://ideone.com/yZHVv

#include<functional>
#include<stdio.h>
main(int c,char **a) {
  char b[30000],g[9999],*f=g,*r=f,*p=b;
  std::function<void()>m[256];
  m['>']=[&p]{p++;};  
  m['<']=[&p]{p--;};
  m['+']=[&p]{(*p)++;};
  m['-']=[&p]{(*p)--;};
  m['.']=[p]{putchar(*p);};
  m[',']=[&p]{*p=getchar();};
  m['[']=[p,&r,&f]{*p?r=f-1:r=0;};
  m[']']=[&r,&f]{r?f=r:r=f;};
  fread(g,1,9999,fopen(a[1],"r"));
  while (c=*(f++))if(m[c]&&(r||c==']'))m[c]();
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.