BrainFlow Tercüman!


11

BrainFlow

BrainFlow nedir?

BrainFlow, ilave işlevsellik ve karışıklık için 3 ek komutla BrainF ** k (BFk) 'nin bir uzantısıdır.

Ne komutları?

Normal BFk komutlarına ek olarak :

^ Hücredeki değere bağlı olarak # hücresine atlar. Örn: 0 hücresindeyken 4 değeri varsa, ^ bizi 4 numaralı hücreye atlar.

= Hücredeki değeri hücrenin dizinine ayarlar. Örn: 4 numaralı hücrede 0 değeri varsa, = değerimizi 4 olarak ayarlar.

& Geçerli hücredeki değeri, geçerli hücremizdeki değere bağlı olarak hücredeki değere eşit olarak ayarlar. (Bu söz etmek zor, işte bir örnek!) Örn: 33 numaralı hücredeyiz ve bu hücredeki şu anki değerimiz 7'dir ve # 33 hücresindeki şu anki değerimizi # 7 hücresindeki herhangi bir değere ayarlayacaktır.

İsteğe Bağlı Zorluklar

Aşağıdakilerden herhangi birini gerçekleştirdiğinizde, belirtilen bonus bayt sayınıza uygulanır.

Interpreter written in BrainFlow (Örnek tarafından yorumlanabilir ve en az bir anlamlı ^ = veya &): Puan / 3

Interpreter written in BrainF**k: Puan / 2

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

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

Misal

Örnek bir Java yorumlayıcısı:

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;
    }
}

Hatta golf yakın değil ama iyi bir başlangıç ​​noktası sağlamalıdır.

Geçerli Challenge indirimleri dikkate alındıktan sonra puanın programınızdaki bayt sayısı olduğu en düşük final puanı kazanır.

Test yapmak

Aşağıdaki BrainFlow programı stdin'den bir '+' karakterini okuduktan sonra belirtilen çıktıyı yazdırmalıdır:

<<,++++[>++++[>++++<-]<-] 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

Çıktı:

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

& Öğesinin temel olarak alt hücrelerde değişkenler oluşturmanıza izin verdiğini ve daha sonra bunlara referans verdiğinizi unutmayın. Örneğin, yaşımı 2. hücrede ve 3. hücrede doğduğum ayı saklıyorsam ve şu anda 64. hücrede yaşıyorsam, yaşımı ++&almak veya +++&doğduğum ayı almak için yapabilirim. tabii ki 64. hücre varsayılan değer 0'dır
spocot

2
Bence alt küme değil, 'süper küme' demek istedin.
Augıʇǝɥʇuʎs

@ değiştirilmiştir ɐɔıʇǝɥʇuʎs subsetiçin extension. Geri dönüşünüz için teşekkür ederiz.
spocot

beyninde yazılma puanı kötü bir fikirdir - brainfuck beyin akışının bir alt kümesidir, bu nedenle herhangi bir brainfuck programı bir beyin akışı programıdır. c ++ programının bir C programından daha iyi puan alacağını söylemek gibi. Tamam, benim C programı bir C ++ programı, soo ....
pseudonym117

1
Brainfuck'ta bir uygulama yazmak neden Brainflow'da yazmaktan daha küçük bir yarar sağlar? Birincisi daha zorlayıcı gibi görünüyor, çünkü daha küçük bir dil.
Peter Olson

Yanıtlar:


7

Perl - 233 230 210 182 180 176 174 171 bayt

$/=$,;%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

Mevcut bir BrainFuck yorumcumu aldım, golf oynadım ve BrainFlow işlevlerini ekledim.

Güncelleme: Programı 28 bayt kaybedecek şekilde tamamen yeniden yapılandırdı.


300 "+" s'lik bir dizeyle beslenirseniz geçersiz değerlerle sonuçlanacağınıza dikkat edin. Bu değerlerin çoğunu ayarladıktan sonra / uygularken% 256 sağlık kontrolü yapmanız gerekir.
user0721090601

Bunun döngülerle ( []) çalışmadığını düşünüyorum . Bunun için karakter karakter değerlendiremezsiniz.
nutki

Artılar tekrar parantez içine nasıl çevrilir?
nutki

6

Hadi bu partiyi başlatalım.

C - 408384393390380357352 bayt (hala parçalanıyor)

gccPOSIX uyumlu bir sistemde derleyin . İlk argüman, yorumlanacak Brainflow kodunu içeren bir dosyanın adıdır. Okunabilirliği artırmak için satırlar eklendi.

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;}}}

Ve eğer ilgilenmediyseniz, ungolfed versiyonu. Herhangi bir hata görürseniz bana bildirin.

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;
            }
    }
}

Güncellemeler:

  • Fazladan 24 bayt kapatmamı sağlayan ilk geri bildirim için teşekkürler.

  • İşaret hatası düzeltildi. 9 bayt daha eklendi.

  • Es1024'ün önerilerine göre 3 bayt daha kaydetti.

  • Es1024'ten daha fazla öneri başına 10 bayt daha kaydetti.

  • Sadece global değişkenlerin 0 olarak başlatıldığını hatırladım. 23 bayt kaydedildi.

  • Arabellek zaten sıfır olarak başlatıldığından, programda null sonlandırıcı ayarlamanıza gerek yoktur. 5 bayt kaydedildi.

2
Bence if () ve; ?: ile değiştirilebilir ve bazı karakterleri kaydedebilir.
Jerry Jeremiah

2
Karakterleri kaydetmek için karakter değişmezleri ASCII eşdeğerleriyle değiştirilebilir.
pseudonym117

1
@Orby Girdi karakterlerini doğru işlemiyor gibi görünüyor. Onları ascii temsiline dönüştürmeli ve saklamalıdır. Bunun dışında çalışıyor.
spocot

1
İki bayt main(int c,char**v){ile değiştirebilir main(c,v)char**v;{ve kaydedebilir, ayrıca int i=0,p=0,b[9999],*k=b;işlevin dışına gidebilir ve int dört bayt kaydetmek için simgesini bırakabilirsiniz . if (c==91)ayrıca gereksiz bir alana sahiptir.
es1024

1
Ayrıca hepsi değilse çoğu yerini alabilir c==[number]?[action]:0;ile c-[number]||[action]. ( c-[number]Eşdeğerdir c != [number]ve if(p)p--;birliktep&&p--;
es1024

6

AppleScript 972 670

Şimdiye kadar kazanacak bir yolu olmamasına rağmen çoğunlukla golf. Neden sadece perl biri gibi bir senaryo oluşturmak hakkında düşünmedim bilmiyorum (yine de haha ​​kazanmayacak olsa da). Bu muhtemelen, dizin değerlerinin nasıl daha iyi olduğunu yeniden ayarlayarak daha fazla golf oynayabilir, AppleScript sinir bozucu bir şekilde (bu tür şeyler için) 1 dizin dili.

BrainFlow kodunu e () öğesine girmeniz yeterlidir. AppleScript'in ASCII komutlarının MacOSRoman kodlamasını kullandığını, bu nedenle çıktı farklı görünecek olsa da, ikili gösterimine bakıldığında doğru olduğunu unutmayın. Üst ASCII karakterlerini "," komutlarında olsa da iletirken bunu dikkate almanız gerekir.

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

(çünkü beyninizle, kafanızla çok fazla eşleşen başka bir dilde bir beyin sikişi / akış yorumlayıcısı yazmaktan daha çok şey nedir?

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.