무작위 Brainfuck 컴파일러


10

Joe는 평균 BF 개발자입니다. 그는 상사로부터 전화를받을 때 코드 변경 사항을 저장소에 체크인하려고합니다. "Joe! 새로운 클라이언트의 시스템이 고장났습니다! brainfuck 인터프리터는 프로그램 실행 전에 모든 셀을 임의의 값으로 설정합니다.이를 고칠 시간이 없으면 코드를 처리해야합니다." Joe는 그것을 많이 생각하지 않고 그의 사장이 그를 다시 방해 할 때 처음으로 백만 개의 셀을 0으로 설정하는 프로그램을 작성하려고합니다. "... 그리고 무차별 대입에 대해 생각하지 마십시오. 코드는 최대한 작아야합니다. " 이제 당신은 가난한 조를 도와야합니다!

명세서

  • 당신은 입력으로 유효한 brainfuck 코드를 얻을 것입니다
  • 그런 다음 프로그램이 코드를 수정하여 임의의 brainfuck 인터프리터에서 작동하도록합니다.
  • 이것은 프로그램 실행 전에 셀을 임의의 값으로 설정할 수 있음을 의미합니다.
  • 새 프로그램은 초기 조건에 관계없이 동일한 동작을 수행해야합니다.
  • 인터프리터는 줄 바꿈 및 무한 길이 테이프로 최대 셀 값이 255입니다.

채점

점수는 바이트 단위의 컴파일러 크기와 테스트 케이스 크기합의 10 배 입니다. 테스트 케이스 최적화를 완화하기 위해, 의심이가는 경우 테스트 케이스를 변경할 권리가 있으며, 승자를 선택하기 전에 변경할 수도 있습니다.

테스트 사례

(나는 esolangs 페이지 와이 웹 페이지 에서 이것을 얻었습니다 : http://www.hevanet.com/cristofd/brainfuck/ ). 또한 마지막 테스트 사례에 대한 @Sparr 덕분입니다.

  • 안녕하세요 세계 : ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
  • 역 입력 : >,[>,]<[.<]
  • 2의 거듭 제곱 (무한 스트림) : >++++++++++>>+<+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<]>.>[->[ <++>-[<++>-[<++>-[<++>-[<-------->>[-]++<-[<++>-]]]]]]<[>+<-]+>>]<<]
  • 10000 미만의 제곱 : ++++[>+++++<-]>[<+++++>-]+<+[>[>+>+<<-]++>>[<<+>>-]>>>[-]++>[-]+>>>+[[-]++++++>>>]<<<[[<++++++++<++>>-]+<.<[>----<-]<]<<[>>>>>[>>>[-]+++++++++<[>-<-]+++++++++>[-[<->-]+[<<<]]<[>+<-]>]<<-]<<-]
  • 피보나치 스트림 : >++++++++++>+>+[[+++++[>++++++++<-]>.<++++++[>--------<-]+<<<]>.>>[[-]<[>+<-]>>[<<+>+>-]<[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>[-]>+>+<<<-[>+<-]]]]]]]]]]]+>>>]<<<]
  • 입력까지의 ASCII 시퀀스 : ,[.[>+<-]>-]( 입력에 따라 다양한 셀 번호가 필요합니다)

의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Martin Ender

답변:


8

sed, 46 바이트 컴파일러

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

나는 프로그램을 작성한 후에야 출력이 골프라고 가정하지 않았으므로 짧은 컴파일러로 갈 것입니다. 또한 테스트하기에는 너무 많은 작업이 있었으므로 제대로 작동하지 않으면 알려주십시오. :)


1
혼란 스러워요. 세 번째 줄은 빈 문자열을 대체합니까? 빈 문자열은 sed에서 무엇입니까? "sed : 첫 번째 RE는 비워 둘 수 없습니다"
Sparr

@Sparr 좋아, 대신 캐럿을 사용해보십시오.
feersum

3
좋아, 내가 따라야하는지 보자 ... 셀 0을 0으로 설정하고 셀 1을 1로 설정하십시오. 모든 <을 <<로 바꾸고>를> X>로 바꾸십시오. 이제 원래 프로그램이 셀 n에 액세스 할 때마다 새 프로그램은 셀 2n, 짝수 번호의 셀에 액세스합니다. X는 전달되는 홀수 셀을 0으로 만들고, 0이 아닌 경우 다음 셀 (짝수 셀)을 0으로 설정하고 다음 홀수 셀을 1로 설정합니다.
Sparr

2
짧은 컴파일러를 사용한다면 Retina 에서는 35 바이트에 불과 합니다. ;)
Martin Ender

1
@ MartinBüttner 뻔뻔한 플러그! : P
Optimizer

2

C ++

컴파일러 크기 : 630 바이트 (Zacharý 덕분에 -10 바이트)
Hello World 컴파일 결과 크기 : 139
10000 미만의 사각형 : 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변경하고 정의를 Rm[p<0?p%30000+30000:p](를) 변경하고 이에 대한 모든 통화 / 참조를 수정 하여 점수를 줄일 수 있습니다 . 또한 테스트 사례를 수정했습니다. 나는 이것을 확인하지 않았지만 30000너무 자주 사용하기 때문에 무언가를 정의하기 위해 바이트를 절약 할 수 있습니다 .
Zacharý

1
겠습니까는 변화 Rm[p<0?p%S+S:p]사용할 수 있습니까?
Zacharý

정의에서 괄호를 제거하면 R몇 바이트를 절약해야합니다.
Zacharý

1

rs , 33 바이트, 점수 : 2659

대부분 간단한 sed답변 포트입니다 .

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

1
어제 전에이 언어를 게시 했습니까? 질문을 만든 날짜 이후의 언어는 답변을 제출할 수 없습니다.
Sparr

@Sparr 글쎄요,하지만 저는 Git 커밋 히스토리를
깨뜨려 서 리포지토리
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.