Interprète BrainFlow!


11

BrainFlow

Qu'est-ce que BrainFlow?

BrainFlow est une extension de BrainF ** k (BFk) avec 3 commandes supplémentaires pour plus de fonctionnalité et de confusion.

Quelles commandes?

En plus des commandes BFk normales , nous avons également:

^ Passe à la cellule # en fonction de la valeur de la cellule. Ex: Si nous sommes à la cellule # 0 avec une valeur de 4, ^ nous sautera à la cellule # 4.

= Définit la valeur de la cellule à l'index de la cellule. Ex: Si nous sommes à la cellule # 4 avec une valeur de 0, = définira notre valeur à 4.

& Fixera la valeur de la cellule actuelle à la valeur de la cellule en fonction de la valeur de notre cellule actuelle. (Celui-ci est difficile à dire, alors voici un exemple!) Ex: Nous sommes à la cellule # 33 et notre valeur actuelle dans cette cellule est 7, et définirons notre valeur actuelle à la cellule # 33 à la valeur de la cellule # 7.

Défis facultatifs

Si vous effectuez l'une des opérations suivantes, le bonus spécifié sera appliqué à votre nombre d'octets.

Interpreter written in BrainFlow (Peut être interprété par l'échantillon et contient au moins un ^ = ou & significatif): Score / 3

Interpreter written in BrainF**k: Score / 2

Doesn't contain any English letters (in either upper or lower case): Score - 20

Doesn't contain any of the BrainFlow / BFk commands in the interpreter itself: Score - 50

Exemple

Un exemple d'interpréteur Java:

import java.util.Scanner;

public class Interpreter {

    private String exp;

    private int[] values = new int[256];
    private int index = 0;

    private Scanner in;

    public Interpreter(String exp, Scanner in){
        this.exp = exp;
        this.in = in;
    }

    public void run(){
        //Reset index and values
        for(int i = 0; i < values.length; i++){
            values[i] = 0;
        }
        this.index = 0;

        System.out.println("Starting...");
        this.process(this.exp, false);
        System.out.println("\nDone.");
    }

    private void process(String str, boolean loop){
        boolean running = loop;
        do{
            for(int i = 0; i < str.length(); i++){
                switch(str.charAt(i)){
                case '>':increaseIndex();break;
                case '<':decreaseIndex();break;
                case '+':increaseValue();break;
                case '-':decreaseValue();break;
                case '[':
                    String s = str.substring(i);
                    int j = this.getClosingIndex(s);
                    if(this.values[this.index] == 0){
                        i +=j;
                        break;
                    }
                    process(s.substring(1, j), true);
                    i += j;
                    break;
                case '.':
                    int v = this.values[this.index];
                    System.out.print((char)v);
                    break;
                case ',':this.values[this.index] =  this.in.next().charAt(0);break;
                case '^':this.index = this.values[this.index];break;// Jumps to the index specified in the current cell.
                case '=':this.values[index] = this.index;break;// Sets the value at cell #x to x
                case '&':this.values[index] = this.values[this.values[index]];break;// If cell contains X, makes value of current cell equal to value in cell X
                default:
                    //Ignore others
                    break;
                }
            }
            if(this.values[this.index] == 0){
                running = false;
            }
        }while(running);
    }

    private void increaseIndex(){
        if(++this.index >= this.values.length){
            this.index = 0;
        }
    }

    private void decreaseIndex(){
        if(--this.index < 0){
            this.index = this.values.length - 1;
        }
    }

    private void increaseValue(){
        int newVal = this.values[this.index] + 1;
        if(newVal >= this.values.length){
            newVal = 0;
        }
        this.values[this.index] =  newVal;
    }

    private void decreaseValue(){
        int newVal = this.values[this.index] - 1;
        if(newVal < 0){
            newVal = this.values.length - 1;
        }
        this.values[this.index] =  newVal;
    }

    private int getClosingIndex(String str){
        int openings = 0;
        int closings = 0;
        for(int i = 0; i < str.length(); i++){
            char c = str.charAt(i);
            if(c == '['){
                openings++;
            }else if(c == ']'){
                closings++;
            }
            if(openings == closings){
                return i;
            }
        }
        return -1;
    }
}

Pas même près du golf mais devrait fournir un bon point de départ.

Le score final le plus bas gagne, où le score est le nombre d'octets dans votre programme après que les réductions de défi applicables ont été prises en compte.

Essai

Le programme BrainFlow suivant devrait imprimer la sortie spécifiée après avoir lu un caractère '+' depuis stdin:

<<,++++[>++++[>++++<-]<-] Set cell #0 to a value dependent on input
>>>+[[-]&>=]+& Set every other cell to that value
[ Start loop
+^ Add one to current value and jump to that cell index
. Print the value at that cell
& Copy value from specified cell
] End loop

Production:

ðñðòñðòðôóòñóñôóðòõóñõðôôóòñööõôöðóöðõðùõñô÷ùõóñöóùñô÷øôøõôòöõóðòöóñ÷ðõôûôòú÷úø÷öùøöùñøðùúðûðþöûñùýøðòñ

Notez que le & vous permet de créer essentiellement des variables dans les cellules inférieures, puis de les référencer plus tard. Par exemple, si je stocke mon âge dans la 2e cellule et le mois de ma naissance dans la 3e cellule et que je suis actuellement dans la 64e cellule, je peux faire ++&pour récupérer mon âge ou +++&pour récupérer le mois de ma naissance. (En supposant bien sûr, la 64e cellule est à la valeur par défaut de 0)
spocot

2
Je pense que vous voulez dire «surensemble», pas sous-ensemble.
ɐɔıʇǝɥʇuʎs

@ ɐɔıʇǝɥʇuʎs Modifié de subsetà extension. Merci pour les commentaires.
spocot

le score pour avoir été écrit dans brainflow est une mauvaise idée - brainfuck est un sous-ensemble de brainflow, donc tout programme brainfuck est un programme de brainflow. c'est comme dire qu'un programme c ++ aura un meilleur score qu'un programme C. OK, mon programme C est un programme C ++, soo ....
pseudonym117

1
Pourquoi l'écriture d'une implémentation dans Brainfuck présente un avantage moindre que l'écriture d'une implémentation dans Brainflow? Il semble que le premier serait plus difficile, car il s'agit d'une langue plus petite.
Peter Olson

Réponses:


7

Perl - 233 230 210 182 180 176 174 174 171 octets

$/=$,;%d=qw(> $p++ < $p-- + $v[$p]++ - $v[$p]-- , $v[$p]=ord+getc . print+chr+$v[$p] [ while+$v[$p]{ ] } ^ $p=$v[$p] = $v[$p]=$p & $v[$p]=$v[$v[$p]]);eval$d{$_}for<>=~/./g

J'ai simplement pris un de mes interprètes BrainFuck, joué au golf et ajouté les fonctions BrainFlow.

Mise à jour: complètement restructuré le programme pour perdre 28 octets.


Notez que si vous deviez recevoir une chaîne de 300 "+", vous vous retrouveriez avec des valeurs non valides. Vous devez effectuer un contrôle de cohérence% 256 après / pendant la définition de plusieurs de ces valeurs.
user0721090601

Je pense que cela ne fonctionne pas avec les boucles ( []). Vous ne pouvez pas évaluer caractère par caractère pour cela.
nutki

Comment les avantages sont-ils traduits en parenthèses?
nutki

6

Que la fête commence.

C - 408384393390380357352 octets (toujours en train de s'écailler)

Compilez avec gccsur un système compatible POSIX. Le premier argument est le nom d'un fichier contenant le code Brainflow à interpréter. Ajout de nouvelles lignes pour améliorer la lisibilité.

i,p,b[9999],*k=b;unsigned char g[9999],a[30000],*d=a;main(c,v)char**v;
{read(open(v[1],0),g,9999);while(c=g[i++]){c-62||d++;c-60||d--;c-43||
(*d)++;c-45||(*d)--;c-46||putchar(*d);c==44?*d=getchar():0;c==94?d=a+*d:0;
c==61?*d=d-a:0;c==38?*d=a[*d]:0;c==93?i=*(--k):0;if(c==91)if(*d)*k++=i-1;else 
while(c=g[i++]){c==91?p++:0;if(c==93)if(p)p--;else break;}}}

Et la version non golfée si vous êtes intéressé. Faites-moi savoir si vous voyez des bugs.

int i, depth, buffer[9999], *stack = buffer;
unsigned char c, program[9999], array[30000], *data = array;

main(int argc, char **argv)
{
    read(open(argv[1], 0), program, 9999);

    while(c = program[i++]){
        if (c=='>') data++;
        if (c=='<') data--;
        if (c=='+') (*data)++;
        if (c=='-') (*data)--;
        if (c=='.') putchar(*data);
        if (c==',') *data=getchar();
        if (c=='^') data=array+*data;
        if (c=='=') *data=data-array;
        if (c=='&') *data=array[*data];
        if (c==']') i=*(--stack);
        if (c=='[')
            if (*data) *stack++=i-1;
            else while (c=program[i++]) {
                    if (c=='[') depth++;
                    if (c==']') if (depth) depth--; else break;
            }
    }
}

Mises à jour:

  • Merci pour les premiers commentaires qui m'ont permis de supprimer 24 octets supplémentaires.

  • Bogue de signe corrigé. Ajout de 9 octets supplémentaires.

  • Enregistré encore 3 octets par les suggestions de es1024.

  • 10 octets supplémentaires enregistrés par plus de suggestions de es1024.

  • Je viens de rappeler que les variables globales sont initialisées à 0. Passé de fread et fopen à lire et ouvrir. Enregistré 23 octets.

  • Vous n'avez pas besoin de définir un terminateur nul sur le programme car le tampon est déjà initialisé à zéro. Enregistré 5 octets.

2
Je pense que le if () et le; pourrait être remplacé par?: et enregistrer certains caractères.
Jerry Jeremiah

2
Les littéraux de caractères peuvent être remplacés par leurs équivalents ASCII pour enregistrer les caractères.
pseudonym117

1
@Orby Il ne semble pas traiter correctement les caractères d'entrée. Il doit les convertir en représentation ascii et les stocker. A part ça ça marche.
spocot

1
Vous pouvez remplacer main(int c,char**v){par main(c,v)char**v;{et enregistrer deux octets, ainsi que passer int i=0,p=0,b[9999],*k=b;à l'extérieur de la fonction et supprimer le int pour enregistrer quatre octets. if (c==91)a également un espace inutile.
es1024

1
Vous pouvez également remplacer la plupart, sinon la totalité, c==[number]?[action]:0;par c-[number]||[action]. ( c-[number]équivaut à c != [number]et if(p)p--;avecp&&p--;
es1024

6

AppleScript 972 670

Surtout au golf, bien qu'il n'y ait aucun moyen de gagner. Je ne sais pas pourquoi je n'ai pas pensé à construire un script comme celui de Perl (même s'il ne gagnera toujours pas haha). Cela pourrait probablement être joué plus en réajustant la façon dont les valeurs d'index un peu mieux, AppleScript est frustrant (pour ce type de choses) un langage d'index 1.

Passez simplement le code BrainFlow à e (). Notez que les commandes ASCII d'AppleScript utilisent le codage MacOSRoman, donc bien que la sortie apparaisse différente, elle est correcte en regardant sa représentation binaire. Vous devrez en tenir compte lorsque vous passerez des caractères ASCII supérieurs dans les commandes ",".

on e(x)
set d to {"", "set b'sitem(i+1)to(b'sitem(i+1)+1)mod 256", "set b'sitem(i+1)to(b'sitem(i+1)+255)mod 256", "set i to(i+1)mod 256", "set i to(i+255)mod 256", "repeat while b'sitem(i+1)≠0", "end", "set o to o&(ASCII character b'sitem(i+1))", "display dialog \"\"default answer\"\"
set b'sitem(i+1)to ASCII number result'stext returned'stext1", "set i to b'sitem(i+1)", "set b'sitem(i+1)to i", "set b'sitem(i+1)to b'sitem(b'sitem(i+1)+1)"}
set s to "set i to 0
set b to{}
repeat 256
set b'send to 0
end
set o to  \"\"
"  
repeat with c in x'stext
set s to s&d'sitem((offset of c in "+-><[].,^=&")+1)&"
"
end
set s to s&"return o"
return run script s
end

(parce que qu'est-ce qui fout le plus votre cerveau que d'écrire un interprète brainfuck / flow dans une autre langue qui fous trop la tête?

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.