คอมไพเลอร์ Brainfuck แบบสุ่ม


10

Joe เป็นนักพัฒนา BF โดยเฉลี่ยของคุณ เขากำลังจะตรวจสอบการเปลี่ยนแปลงรหัสของที่เก็บของพวกเขาเมื่อเขาได้รับโทรศัพท์จากเจ้านายของเขา "โจ! เครื่องของลูกค้าใหม่เสีย! ตัวแปล brainfuck ตั้งค่าเซลล์ทั้งหมดให้เป็นค่าสุ่มก่อนที่โปรแกรมจะทำงานไม่มีเวลาแก้ไขรหัสของคุณจะต้องจัดการกับมัน" โจไม่ได้คิดมากและกำลังจะเขียนโปรแกรมเพื่อกำหนดล้านเซลล์แรกให้เป็นศูนย์เมื่อหัวหน้าของเขาขัดจังหวะเขาอีกครั้ง - "... และไม่คิดที่จะใช้กำลังดุร้ายรหัสจะต้อง เล็กที่สุด " ตอนนี้คุณต้องช่วยโจผู้น่าสงสาร!

ข้อมูลจำเพาะ

  • คุณจะได้รับรหัส brainfuck ที่ถูกต้องเป็นข้อมูลเข้า
  • โปรแกรมของคุณจะแก้ไขโค้ดเพื่อให้สามารถทำงานกับล่าม brainfuck แบบสุ่ม
  • ซึ่งหมายความว่าก่อนการเรียกใช้งานโปรแกรมเซลล์สามารถกำหนดเป็นค่าใดก็ได้
  • โปรแกรมใหม่ควรมีพฤติกรรมเหมือนกันทุกประการ
  • ล่ามจะมีค่าสูงสุดของเซลล์ 255 ด้วยการห่อและเทปความยาวไม่ จำกัด

เกณฑ์การให้คะแนน

คะแนนของคุณเป็น10 เท่าของขนาดคอมไพเลอร์ไบต์บวกผลรวมของขนาดกรณีทดสอบ เห็นได้ชัดว่าได้คะแนนต่ำสุดเพื่อลดผลกระทบจากการเพิ่มประสิทธิภาพของกรณีทดสอบฉันขอสงวนสิทธิ์ในการเปลี่ยนแปลงกรณีทดสอบหากฉันสงสัยอะไรและอาจจะทำได้ก่อนเลือกผู้ชนะ

กรณีทดสอบ

(ฉันได้รับสิ่งเหล่านี้จากหน้า esolangsและหน้าเว็บนี้: http://www.hevanet.com/cristofd/brainfuck/ ) ขอขอบคุณ @Sparr สำหรับกรณีทดสอบครั้งสุดท้าย

  • สวัสดีชาวโลก: ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
  • ย้อนกลับอินพุต: >,[>,]<[.<]
  • พลังของสอง (สตรีมไม่สิ้นสุด): >++++++++++>>+<+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<]>.>[->[ <++>-[<++>-[<++>-[<++>-[<-------->>[-]++<-[<++>-]]]]]]<[>+<-]+>>]<<]
  • กำลังสองต่ำกว่า 10,000: ++++[>+++++<-]>[<+++++>-]+<+[>[>+>+<<-]++>>[<<+>>-]>>>[-]++>[-]+>>>+[[-]++++++>>>]<<<[[<++++++++<++>>-]+<.<[>----<-]<]<<[>>>>>[>>>[-]+++++++++<[>-<-]+++++++++>[-[<->-]+[<<<]]<[>+<-]>]<<-]<<-]
  • สตรีม Fibonacci: >++++++++++>+>+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<<]>.>>[[-]<[>+<-]>>[<<+>+>-]<[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>[-]>+>+<<<-[>+<-]]]]]]]]]]]+>>>]<<<]
  • ASCII Sequence จนถึงอินพุต: ,[.[>+<-]>-](อันนี้ต้องใช้จำนวนเซลล์ที่แตกต่างกันตามอินพุต)

ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
Martin Ender

คำตอบ:


8

sed, คอมไพเลอร์ 46 ไบต์

s/</<</g
s/>/>[->[-]>[-]+<<]>/g
s/^/[-]>[-]+</

ฉันไม่ได้สังเกตว่าผลลัพธ์ที่ควรจะเป็นกอล์ฟจนกว่าจะเขียนโปรแกรมดังนั้นฉันจะไปรวบรวมสั้น ยิ่งไปกว่านั้นมันเป็นงานทดสอบที่มากเกินไปดังนั้นโปรดแจ้งว่ามันทำงานไม่ถูกต้องหรือไม่ :)


1
ฉันสับสน บรรทัดที่สามของคุณแทนที่สตริงว่างหรือไม่ สตริงว่างเปล่าตรงกับอะไร? "sed: RE ครั้งแรกอาจไม่ว่างเปล่า"
Sparr

@ Sparr เอาล่ะลองใช้ caret แทน
feersum

3
ตกลงมาดูกันว่าฉันทำตาม ... 0 ศูนย์เซลล์ตั้งค่าเซลล์ 1 เป็นหนึ่ง แทนที่ <ด้วย << และ> ด้วย> X> ทั้งหมด ตอนนี้เมื่อใดก็ตามที่โปรแกรมดั้งเดิมเข้าถึงเซลล์และโปรแกรมใหม่เข้าถึงเซลล์ 2n ซึ่งเป็นเลขคู่ X เลขศูนย์เซลล์คี่ที่ถูกส่งผ่านและถ้ามันไม่เป็นศูนย์ก็จะทำการศูนย์เซลล์ถัดไป (เซลล์คู่) และตั้งค่าเซลล์คี่ถัดไปเป็น 1 ฉันมีสิทธิไหม
Sparr

2
คุณจะรู้ว่าถ้าคุณกำลังจะหาคอมไพเลอร์สั้นนี้จะเป็นเพียง 35 ไบต์ในจอประสาทตา ;)
Martin Ender

1
@ MartinBüttnerเสียบไร้ยางอาย! : P
เครื่องมือเพิ่มประสิทธิภาพ

2

C ++

ขนาดคอมไพเลอร์: 630 ไบต์ (-10 ไบต์ขอบคุณZacharý)
Hello World ขนาดผลลัพธ์การรวบรวม: 139
ตารางต่ำกว่า 10,000: 319

ผู้เรียบเรียง:

#include<string>
#include<map>
#include<stack>
#define B break
#define C case
#define S 30000
#define R m[(p<0)?(p%S)+S:p]
using s=std::string;using P=std::pair<int,int>;s a(s c){char m[S];memset(m,0,S);int p=0,i=0;P r{0,0};std::map<int,int>j;std::stack<int>t;for(int d=0;d<c.size();++d){if(c[d]==91)t.push(d);if(c[d]==93){j[d]=t.top();j[t.top()]=d;t.pop();}}while(i<c.size()){switch(c[i]){C'>':++p;B;C'<':--p;B;C'+':++R;B;C'-':--R;B;C'[':if(!R)i=j[i];B;C']':i=j[i]-1;B;default:B;}++i;r.first=p<r.first?p:r.first;r.second=p>r.second?p:r.second;}s n;for(int i=r.first;i<r.second;++i){n+="[-]>";}n+="[-]"+s(r.second,60)+c;return n;}

ล่าม brainfuck แบบสุ่ม:

void interpret(const std::string& code) {
    char memory[30000];
    for (int i = 0; i < 30000; ++i)
        memory[i] = std::rand()%256;
    int memPtr = 0, insPtr = 0;
    std::map<int, int> jump_map;

    {
        std::stack<int> jstack;
        for (int i = 0; i < code.size(); ++i) {
            if (code[i] == '[')
                jstack.push(i);
            if (code[i] == ']') {
                jump_map[i] = jstack.top();
                jump_map[jstack.top()] = i;
                jstack.pop();
            }
        }
    }
    while (insPtr < code.size()) {
        switch (code[insPtr]) {
        case '>': ++memPtr; break;
        case '<': --memPtr; break;
        case '+': ++memory[memPtr]; break;
        case '-': --memory[memPtr]; break;
        case '.': std::cout << memory[memPtr]; break;
        case ',': std::cin >> memory[memPtr]; break;
        case ']': if (memory[memPtr] != 0) insPtr = jump_map[insPtr]; break;
        case '[': if (memory[memPtr] == 0) insPtr = jump_map[insPtr]; break;
        default:break;
        }
        ++insPtr;
    }
}

หมายเหตุบางส่วน:

  • คอมไพเลอร์จะดำเนินการโปรแกรมเพื่อกำหนดเซลล์หน่วยความจำที่ใช้ หากโปรแกรมของคุณเป็นลูปไม่สิ้นสุดคอมไพเลอร์จะวนซ้ำไม่สิ้นสุด

คุณสามารถลดคะแนนของคุณโดยการเปลี่ยนชื่อของpiiเป็นPและเปลี่ยนนิยามของRเป็นm[p<0?p%30000+30000:p]และแก้ไขการโทร / การอ้างอิงทั้งหมดให้สอดคล้อง นอกจากนี้เขาปรับเปลี่ยนกรณีทดสอบ ฉันไม่ได้ตรวจสอบสิ่งนี้ แต่อาจบันทึกบางไบต์เพื่อกำหนดสิ่งที่จะ30000เนื่องจากคุณใช้บ่อย
Zacharý

1
จะเปลี่ยนRไปm[p<0?p%S+S:p]ทำงานเหรอ
Zacharý

การลบวงเล็บในคำจำกัดความของRควรบันทึกสองสามไบต์
Zacharý

1

rs , 33 bytes, คะแนน: 2659

ส่วนใหญ่เป็นเพียงsedคำตอบง่ายๆ

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

1
คุณเผยแพร่ภาษานี้ก่อนหน้านี้เมื่อวานนี้หรือไม่? ภาษาที่โพสต์วันที่สร้างคำถามไม่ถูกต้องสำหรับการส่งคำตอบ
Sparr

@ Sparr ดีฉันมี แต่แล้วฉันทำลาย Git ของฉันกระทำประวัติศาสตร์และต้องสร้าง repo อีกครั้ง ...
kirbyfan64sos
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.