Thông dịch viên BrainFlow!


11

BrainFlow

BrainFlow là gì?

BrainFlow là một phần mở rộng của BrainF ** k (BFk) với 3 lệnh bổ sung để thêm chức năng và nhầm lẫn.

Lệnh nào?

Ngoài các lệnh BFk bình thường , chúng ta cũng có:

^ Nhảy tới ô # tùy thuộc vào giá trị trong ô. Ví dụ: Nếu chúng ta ở ô số 0 với giá trị là 4, ^ sẽ chuyển chúng ta đến ô số 4.

= Đặt giá trị tại ô thành chỉ mục của ô. Ví dụ: Nếu chúng tôi ở ô số 4 có giá trị 0, = sẽ đặt giá trị của chúng tôi thành 4.

& Sẽ đặt giá trị tại ô hiện tại bằng với giá trị tại ô dựa trên giá trị trong ô hiện tại của chúng tôi. .

Thử thách không bắt buộc

Hoàn thành bất kỳ điều nào sau đây sẽ áp dụng phần thưởng được chỉ định cho số byte của bạn.

Interpreter written in BrainFlow (Có thể được giải thích bởi mẫu và chứa ít nhất một ý nghĩa ^ = hoặc &): Điểm / 3

Interpreter written in BrainF**k: Điểm / 2

Doesn't contain any English letters (in either upper or lower case): Điểm - 20

Doesn't contain any of the BrainFlow / BFk commands in the interpreter itself: Điểm - 50

Thí dụ

Một trình thông dịch Java mẫu:

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

Thậm chí không gần với golf nhưng nên cung cấp một điểm khởi đầu tốt.

Điểm số cuối cùng thấp nhất sẽ thắng, trong đó điểm là số byte trong chương trình của bạn sau khi đã giảm các Thử thách áp dụng.

Kiểm tra

Chương trình BrainFlow sau đây sẽ in đầu ra được chỉ định sau khi đọc char '+' từ 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

Đầu ra:

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

Lưu ý rằng & cho phép bạn về cơ bản tạo các biến trong các ô thấp hơn sau đó tham chiếu chúng sau. Ví dụ: nếu tôi lưu trữ tuổi của mình trong ô thứ 2 và tháng tôi được sinh ra ở ô thứ 3 và hiện tại tôi đang ở ô thứ 64, tôi có thể làm gì ++&để lấy lại tuổi của mình hoặc +++&lấy lại tháng tôi sinh ra. (Giả sử tất nhiên ô thứ 64 có giá trị mặc định là 0)
spocot

2
Tôi nghĩ bạn có nghĩa là 'superset', không phải tập hợp con.
ɐɔıʇǝɥʇuʎs

@ ɐɔıʇǝɥʇuʎs Thay đổi từ subsetđến extension. Cảm ơn vì bạn đã phản hồi.
spocot

Điểm cho việc được viết trong dòng chảy não là một ý tưởng tồi - brainfuck là một tập hợp con của dòng chảy não, do đó, bất kỳ chương trình brainfuck nào cũng là một chương trình não. Nó giống như nói một chương trình c ++ sẽ ghi điểm tốt hơn một chương trình C. OK, chương trình C của tôi là chương trình C ++, vì vậy ....
bút danh

1
Tại sao viết một triển khai trong Brainfuck có lợi ích nhỏ hơn so với viết trong Brainflow? Có vẻ như trước đây sẽ có nhiều thách thức hơn, vì nó là một ngôn ngữ nhỏ hơn.
Peter Olson

Câu trả lời:


7

Perl - 233 230 210 182 180 176 174 171 byte

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

Đơn giản chỉ cần lấy một trình thông dịch BrainFuck hiện có của tôi, đánh gôn và thêm các chức năng BrainFlow.

Cập nhật: Cấu trúc lại hoàn toàn chương trình để mất 28 byte.


Lưu ý rằng nếu bạn được cung cấp một chuỗi 300 "+", bạn sẽ có các giá trị không hợp lệ. Bạn cần thực hiện kiểm tra độ chính xác% 256 sau / trong khi đặt nhiều giá trị đó.
user0721090601

Tôi nghĩ rằng điều này không làm việc với các vòng lặp ( []). Bạn không thể đánh giá nhân vật theo nhân vật cho điều đó.
nutki

Làm thế nào các dấu cộng được dịch trở lại trong ngoặc đơn?
nutki

6

Hãy bắt đầu bữa tiệc nào.

C - 408 384 393 390 380 357 352 byte (vẫn bị sứt mẻ)

Biên dịch gcctrên hệ thống tuân thủ POSIX. Đối số đầu tiên là tên của một tệp chứa mã Brainflow sẽ được diễn giải. Dòng mới được thêm vào để cải thiện khả năng đọc.

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

Và phiên bản không có bản quyền nếu bạn quan tâm. Hãy cho tôi biết nếu bạn thấy bất kỳ lỗi.

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

Cập nhật:

  • Cảm ơn phản hồi ban đầu cho phép tôi loại bỏ thêm 24 byte.

  • Đã sửa lỗi. Đã thêm 9 byte.

  • Đã lưu thêm 3 byte cho mỗi đề xuất của es1024.

  • Đã lưu thêm 10 byte cho mỗi đề xuất khác từ es1024.

  • Chỉ cần nhớ rằng các biến toàn cục được khởi tạo thành 0. Chuyển từ fread và fopen sang đọc và mở. Đã lưu 23 byte.

  • Không cần thiết lập null terminator trên chương trình vì bộ đệm đã được khởi tạo về 0. Đã lưu 5 byte.

2
Tôi nghĩ rằng nếu () và; có thể được thay thế bằng ?: và lưu một số ký tự.
Jerry Jeremiah

2
Các ký tự có thể được thay thế bằng các tương đương ASCII của chúng để lưu các ký tự.
bút danh

1
@Orby Dường như không xử lý chính xác các ký tự đầu vào. Nó nên chuyển đổi chúng thành đại diện ascii và lưu trữ chúng. Khác hơn là nó hoạt động.
spocot

1
Bạn có thể thay thế main(int c,char**v){bằng main(c,v)char**v;{và lưu hai byte, cũng như di chuyển int i=0,p=0,b[9999],*k=b;ra ngoài hàm và thả int để lưu bốn byte. if (c==91)cũng có một không gian không cần thiết.
es1024

1
Bạn cũng có thể thay thế hầu hết nếu không phải tất cả c==[number]?[action]:0;với c-[number]||[action]. ( c-[number]tương đương với c != [number]if(p)p--;vớip&&p--;
es1024

6

AppleScript 972 670

Chủ yếu là chơi gôn mặc dù không có cách nào nó sẽ giành chiến thắng. Tôi không biết tại sao tôi không nghĩ về việc xây dựng một kịch bản giống như kịch bản đã làm (mặc dù nó vẫn không thắng được haha). Điều này có lẽ có thể được đánh gôn nhiều hơn bằng cách điều chỉnh làm thế nào giá trị của chỉ số tốt hơn một chút, AppleScript thật bực bội (đối với loại công cụ này) một ngôn ngữ 1 chỉ mục.

Chỉ cần chuyển mã BrainFlow vào e (). Lưu ý rằng các lệnh ASCII của AppleScript sử dụng mã hóa MacOSRoman, do đó, trong khi đầu ra sẽ xuất hiện khác nhau, thì việc xem xét biểu diễn nhị phân của nó là chính xác. Bạn sẽ cần tính đến điều đó khi chuyển vào bất kỳ ký tự ASCII nào phía trên mặc dù trên các lệnh ",".

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

(bởi vì những gì f *** s với bộ não của bạn nhiều hơn là viết một trình thông dịch não bộ / dòng chảy bằng ngôn ngữ khác mà f *** s với đầu của bạn quá nhiều?

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.