멍청한 번역기 쓰기


18

프로그래밍 또는 스크립팅 언어 x 에서 stdin에서 유효한 brainfuck 소스 코드를 가져 와서 언어 x로 작성된 프로그램의 소스 코드 인 stdout 에 brainfuck 프로그램과 정확히 동일한 결과를 출력 하는 프로그램을 작성 하십시오.

프로그램은 빈 파일을 포함하여 유효한 brainfuck 프로그램에서 작동해야합니다.

점수는 소스 코드의 바이트 수와 다음 입력이 주어진 경우 출력의 바이트 수와 같습니다.

+++++ [-]
+++++ +++++ [
    > +++++ ++
    > ++ +++ ++++ +
    > +++
    <<< -
]
> ++ . H
> + . e
++ +++ ++. l
. l
+++ . o
> ++ . space
< +++++ +++ . w
----- --- . o
+++ . r
---- - - . l
----- --- . d
> + . exclamation mark
------lol; useless code :-)--------------------------[.............................................][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]<-<<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><

예를 들어의 입력의 [-]경우 출력 *p=0;while(*p) *p--;

비 ASCII 문자를 사용하는 경우 바이트 수는 UTF-8 인코딩을 사용하여 계산해야합니다.

최저 점수가 이깁니다. 그러나 산출물을 최소화하려는 창의적인 솔루션은 공감대가 장려해야합니다.


11
당신은 목표 언어도 brainfuck가 아니라는 조항을 추가하고 싶을 수도있다;)
Josh

@Josh 글쎄, 누군가가 불필요한 쓸데없는 코드를 제거하는 간단한 brainfuck 프로그램을 작성했다면 왜 그렇게하지 않습니까?
user12205

2
소스를 변경하지 않고 출력하는 사소한 해결책이 어쨌든 두뇌 성교에서 실제로 점수가 낮을 것입니다. 다른 언어가 그것을 이길 수 있다면 놀랄 것입니다.
Tim Seguine

@Tim Seguine 질문을 변경할 수는 있지만 이미 답변을 제공 한 사람들에게는 불공평합니까? 그리고 질문을 변경하면 점수 계산을 변경하고 결과 byte count of source + (byte count of output)^2를 단순화하여 사람들이 결과를 단순화하는 데 더 집중하도록 장려하고 싶습니다.
user12205

일반적으로 이미 답변을받은 후와 같은 질문을 바꾸는 것은 뿌연 다. 나는 조쉬가 옳다고 생각하는 이유를 지적하고 있었다. 샌드 박스에 먼저 이와 같은 내용을 게시하는 것이 좋으므로 모든 사람에게 공정한 동안 잠재적 인 문제를 해결할 수 있습니다.
Tim Seguine

답변:


12

Perl-177 (소스) + 172 (출력) = 349

#!perl -p0
y/-+><.,[]
-~/p-w/d;s/(.)\K\1+|rs|wv[^v]*(?=w)/$+&&length$&/ge;$_="eval'r$_'=~".'s/.(\d*)/(qw(--$ ++$ -- ++ print+chr$ $$i=ord+getc; while($$i){ })[$&&v63].q($i;))x($++1)/ger'

shebang을 각 옵션 당 하나씩 2 바이트로 계산합니다. 먼저, 8 개의 명령 각각은 range로 변환되고 p-w동시에 다른 모든 문자는 제거됩니다. 그런 다음이 문자열은 실행 길이 인코딩되어 최소 디코더 / 통역사로 출력됩니다. 몇 가지 사항이 최적화되어 있습니다. 문자열은 ><분명히 아무 것도 수행하지 않으며 입력 루프가 절대로 입력되지 않으므로 다른 루프 바로 다음에 오는 for 루프는 완전히 제거 될 수 있습니다.

테스트 프로그램의 출력 :

eval'rq4vpwq9vrq6rq9rq2s2pwrq1trqtq6t1q2trq1tsq7tp7tq2tp5tp7trqtp32vt44wsps1'=~s/.(\d*)/(qw(--$ ++$ -- ++ print+chr$ $$i=ord+getc; while($$i){ })[$&&v63].q($i;))x($++1)/ger

샘플 런 :

$ perl brainfusk.pl < in.bf | perl
Hello world!

Perl-232 (소스) + 21 (출력) = 253

#!perl -p0
y/-+><.,[]
-~/0-7/d;$_="eval'2$_'=~".'s/./qw(--$ ++$ -- ++ print+chr$ $$i=ord+getc; while($$i){ })[$&].q($i;)/ger';
/5/||fork?(wait,$?||exit):($SIG{ALRM}=sub{exit 1},alarm 9,$S=select(open 1,'>',\$o),eval,print$S "print\"\Q$o\E\"")

이것은 원래 프로그램에 입력 명령문이 포함되지 않은 경우 출력이 정적이므로 단일 명령문 으로 축소 될 수 있다는 FIQ 의 관찰을 기반으로 print합니다. 당신이 이것을 좋아한다면, 그의 대답 에 +1 을 주어야한다 .

그래서 우리가 할 수있는 것은 stdout변수 로 파이프 하고, eval우리가 출력 한 코드를 결과를로 감싸는 것 print입니다.

...하지만 항상 작동하지는 않습니다. 번역 할 수있는 코드가 무한 루프 이어질 것입니다 때마다 (예를 들어 +[.]), 이것은 할 수없는 단일로 감소 할 print분명한 이유, 문. 대신 eval짧은 시간 초과로 하위 프로세스 에서을 시작하고 그 시간 내에 실행이 완료되지 않으면 이전과 같이 번역 된 프로그램을 출력합니다.

구조화 및 의견 :

if(!/5/) { # no `,` in program

  if(fork) { # parent process

    # wait for child
    wait;
    # no child error, terminate without output
    $?||exit

  } else { # child process

    # alarm handler, exit with error
    $SIG{ALRM}=sub{exit 1};
    # set an alarm in 9 seconds
    alarm 9;
    # redirect STDOUT to variable $o
    $S=select open 1,'>',\$o;
    # execute translated code
    eval;
    # wrap the result in a print statement
    print$S "print\"\Q$o\E\""
  }
}

샘플 프로그램 출력 :

print"Hello\ world\!"

에 대한 출력 ,[.]:

eval'25647'=~s/./qw(--$ ++$ -- ++ print+chr$ $$i=ord+getc; while($$i){ })[$&].q($i;)/ger

+[.]9 초 후 출력 :

eval'21647'=~s/./qw(--$ ++$ -- ++ print+chr$ $$i=ord+getc; while($$i){ })[$&].q($i;)/ger

1
이거 엄청나 네! 뇌가 아프다 :)
Timwi

나는 wv.*?(?=w)틀렸다고 생각한다 . 나는 그것이 다음 코드까지만 제거 할 것이라고 생각 ]하지만, 당신은 일치하는 것을 찾아야한다 ]. 당신은 중첩 처리해야합니다 ...
Timwi

@Timwi 고정 된 경우를 무시 wv[^v]*(?=w)하여 대안보다 훨씬 짧습니다.
primo

14

Brainfuck, 5 + 540 = 545 바이트

5 바이트의 코드, 주어진 테스트 파일의 출력에서 ​​540 (그 코드의 붙여 넣기에서 카운트를 얻은 것으로 가정).

,[.,]

EOF가 0이라고 가정합니다.


EOF에서 값을 변경하지 않는 인터프리터를 읽기 전에 재설정되지 않기 때문에 @primo는이 프로그램을 0 바이트보다 큰 모든 입력에 대해 무한 루프로 만듭니다.
Sylwester

이 소프트웨어를 실행하는 데 어떤 소프트웨어가 사용되는지 궁금합니다. xD
Teun Pronk

@TeunPronk bfi ( github.com/susam/bfi ) 라는 brainfuck 인터프리터가 있습니다 . 그냥 컴파일하고 설치하고 다음과 같이 실행하십시오 . brainfuck 파일이 해석 bfi input.bf되는 위치 input.bf는 어디 입니까?
Braden Best

5

PHP, 553 + 27 = 580 바이트

(모든 공백, 즉 개행 및 공백이있는 553 바이트 제거)

나는 PHP를 골퍼하는 일에 열심이다. 그래서이 접근법은 크게 최적화 될 수있다. 나는 주로 BF가 아닌 솔루션에 대한 나의 접근 방식을 보여주고 싶었습니다.

<?php
echo "<?php ";
$x = 'if (!$b) $c = $_GET[c];
$x=$y=$n[0]=$p=0;$o[0]=1;$d="";
while($a=$c[$x++]){
    if($o[$p]){
        if($a=="-")$m[$y]--;
        if($a=="+")$m[$y]++;
        $m[$y]=$m[$y]%256;
        if($a=="<")$y--;
        if($a==">")$y++;
        if($a=="."){
            $e=chr($m[$y]);
            if ($b) echo $e;
            else $d.=addslashes($e);
        }
        if($a==",")$m[$y]=($b=$_GET[i])?ord($b):0;
    }if($a=="["){
        $p++;
        $n[$p]=$x-1;
        $o[$p]=$o[$p-1]?$m[$y]:0;
    }
    if($a=="]"){
        if($o[$p])$x=$n[$p];
        $p--;
        if($p=-1)$p=0;
    }
}
if (!$b) echo "echo \'$d\';";';
if (strstr($_GET['c'],",")) {
    $x = '$b=1;'.$x;
    echo '$c="'.addslashes($_GET[c]).'";'.$x;
    return;
}
eval($x);

오류보고가 꺼져 있어야합니다. 그렇지 않으면 PHP가 당신을 미워할 것입니다. 사용법 : 이것을 페이지로 던져서 script.php? c = CODE로 실행하십시오 (결과 스크립트에 입력이 필요한 경우 out.php? i = INPUT으로 실행하십시오). 입력에서 URL을 이스케이프 처리해야합니다!

이것이하는 것은 기본적으로 이것입니다-BF 스크립트에 ","가 포함되어 있다면, $ b = 1이 붙은 결과 스크립트로 포함됩니다. 상단에. ","를 포함하지 않으면 "echo '<BF output>'"으로 최적화합니다. 편리하게도 OP의 테스트 스크립트에는 입력이 필요하지 않습니다. addslashes ()는 '와 \를 이스케이프하기 위해 존재합니다.


4

C ++, 695 + 510 = 1205 바이트

암호:

#include<iostream>
#include<utility>
#include<vector>
#define D "\n#define "
using namespace std;using S=string;int main(){vector<pair<S,S>>m={{"--------","(*p)-=8;"},{"<>",""},{"[]","F;"},{"+","A;"},{"-","B;"},{">","C;"},{"<","D;"},{"[","F{"},{"]","}"},{".","E;"},{",","std::cin>>*p;"}};S s;char c;while(cin>>c)if(S("+-><[].,").find(c)<8)s+=c;for(int i=0;i<s.length();i++)if(s.substr(i,4)=="[][]")s=s.replace(i--,4,"[]");cout<<"#include<iostream>" D"A ++*p" D"B --*p" D"C p++" D"D p--" D"E std::cout<<*p" D"F while(*p)\nint main(){char*p=new char[1<<19]();";while(s.size())for(auto p:m)if(s.substr(0,p.first.length())==p.first){s=s.substr(p.first.length());cout<<p.second;break;}cout<<"}";}

산출:

#include<iostream>
#define A ++*p
#define B --*p
#define C p++
#define D p--
#define E std::cout<<*p
#define F while(*p)
int main(){char*p=new char[1<<19]();A;A;A;A;A;F{B;}A;A;A;A;A;A;A;A;A;A;F{C;A;A;A;A;A;A;A;C;A;A;A;A;A;A;A;A;A;A;C;A;A;A;D;D;D;B;}C;A;A;E;C;A;E;A;A;A;A;A;A;A;E;E;A;A;A;E;C;A;A;E;D;A;A;A;A;A;A;A;A;E;(*p)-=8;E;A;A;A;E;B;B;B;B;B;B;E;(*p)-=8;E;C;A;E;(*p)-=8;(*p)-=8;(*p)-=8;(*p)-=8;B;F{E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;E;}F;D;B;D;D;}

원본 코드 :

#include <iostream>
#include <utility>
#include <vector>
using namespace std;
int main() {
    vector<pair<string, string>> m={
    {"--------","(*p)-=8;"},
    {"<>",""},
    {"[]","F;"},
    {"+","A;"},
    {"-","B;"},
    {">","C;"},
    {"<","D;"},
    {"[","F{"},
    {"]","}"},
    {".","E;"},
    {",","std::cin>>*p;"}};
    string s;
    char c;
    while (cin >> c)
        if (string("+-><[].,").find(c) < 8)
            s += c;
    for(int i = 0; i < s.length(); i++)
        if(s.substr(i, 4) == "[][]")
            s = s.replace(i--, 4, "[]");
    cout << "#include<iostream>\n"
            "#define A ++*p\n"
            "#define B --*p\n"
            "#define C p++\n"
            "#define D p--\n"
            "#define E std::cout<<*p\n"
            "#define F while(*p)\n"
            "int main(){char*p=new char[1<<19]();";
    while (s.size())
        for (auto p : m)
            if (s.substr(0, p.first.length()) == p.first) {
                s = s.substr(p.first.length());
                cout << p.second;
                break;
            }
    cout << "}";
}

2

파이썬-514 + 352 = 866

암호:

import sys,zlib,base64
s,i="import sys\na,i=[0]*300000,0\n",0
for c in sys.stdin.read():
 if c in"+-><,.[]":
  s+=" "*i+{'+':"a[i]+=1\n",'-':"a[i]-=1\n",'>':"i+=1\n",'<':"i-=1\n",',':"a[i]=(lambda x:0if x==''else ord(x))(sys.stdin.read(1))\n",".":"sys.stdout.write(chr(a[i]))\n","[":"while a[i]!=0:\n","]":"pass\n"}[c]
  i+={'[':1,']':-1}.get(c,0)
print('import zlib,base64\nexec(zlib.decompress(base64.b64decode("'+base64.b64encode(zlib.compress(bytes(s,"utf8"),9)).decode("utf8")+'")).decode("utf8"))')

산출:

import zlib,base64
exec(zlib.decompress(base64.b64decode("eNrLzC3ILypRKK4s5krUybSNNojVMjYAAR0DrsTozFhtW0OCdHlGZk6qAoinaGtgxQVm6QLFFQoSi4uJNoVc2zJBggowWTIZVDGEEvMzddFJ1FDMxBYUwFjTKy5JyS8t0SsvyixJ1UjOKNIASWpqomrAp5DceMBnJjn2Ee0ZojToUiGlEfIFzA5yaGqHELXtp5XfMukVwMOFRi/u8IXZqOSo5KjkqOSIlAQ3k9BLy1HBUcFRwVFBOgpmIrfeMhGE9ihrpLEAudg3NA==")).decode("utf8"))

1

io

659 + 553 = 1212

File standardInput readBufferOfLength(1)바이트 수를 실제로 죽이는 것 같지만 해결할 수는 없습니다. BF 프로그램에서 반복되는 기호 또는 입력 부족에 대한 최적화를 수행하지 않았지만 io의 메타 프로그래밍 기능을 사용하는 작업도 계속 진행할 것입니다.

"v :=Vector clone setSize(30000)
p :=0
z :=getSlot(\"method\")
j :=z(p=p+1)
k :=z(p=p-1)
a :=z(v at(p))
l :=z(v atPut(p,a+1))
m :=z(v atPut(p,a-1))
n :=z(a asCharacter print)
u :=getSlot(\"while\")
o :=z(v atPut(p,File standardInput readBufferOfLength(1)))"println
z :=getSlot("method")
g :=z(a,b,if(a,a,b))
v :=z(e,f,if((x :=s)==e,nil,f .. g(w(x),"")))
s :=z(File standardInput readBufferOfLength(1))
w :=z(c,c switch(">",v("<","j"),"<","k","+","l","-","m",".","n",",","o","[",v("]","u(a>0,"),"]",")"))
while((c :=s)!=nil,if((t :=w(c))!=nil,t println))

테스팅

cat test.bf | io bftrans.io > out.io && io out.io && echo && echo  $(cat out.io | wc -c) " + " $(cat bftrans.io | wc -c) " = "$(($(cat bftrans.io | wc -c) + $(cat out.io | wc -c)))

수확량

Hello world!
659  +  553  = 1212


0

루아-328 + 2256 = 2584

(오, 방금 결과의 길이를 추가해야한다는 것을 깨달았습니다. 점수가 낮습니다.)

print((("l,m,p=loadstring,{0},1 z,y,x,w,v,u=l'io.write(string.char(@))',l'@=io.read(1):byte()',l'p=p-1',l'p=p+1 @=@or 0',l'@=(@+1)%256',l'@=(@-1)%256'"..io.read"*a":gsub("[^.,<>[%]+-]",""):gsub(".",{["."]="z()",[","]="y()",["<"]="x()",[">"]="w()",["["]="while @~=0 do ",["]"]="end ",["+"]="v()",["-"]="u()"})):gsub("@","m[p]")))

에서 촬영 내 대답.


0

루아-319 + 21 = 340

이것은 아마도 가장 짧은 코드 일 것입니다. 그러나 입력을 받아들이지 않으므로 다소 불쾌합니다. 입력이있는 다른 버전에 대한 아이디어가 있습니다.이 주석의 끝을 참조하십시오.

loadstring("o=\"\";d={"..string.rep("0,",30000).."}p=1;"..io.read():gsub("[^%+%-<>%.,%[%]]+",""):gsub(".",{["+"]="d[p]=d[p]+1;",["-"]="d[p]=d[p]-1;",[">"]="p=p+1;",["<"]="p=p-1;",["."]="o=o..string.char(d[p])",[","]="d[p]=io.read()",["["]="while d[p]~=0 do ",["]"]="end;"}))()print("print("..string.format("%q",o)..")")

루아-376 + 366 = 742

이 버전은 루아가 2584보다 낫다는 것을 증명하기위한 것입니다. : D

print('loadstring("d={"..string.rep("0,",30000).."}p=1;"..('..string.format("%q",io.read():gsub("[^%+%-<>%.,%[%]]+",""):gsub("%[[^%+%-<>%,%[%]]*%]",""):match("(.*[.,]).-"))..'):gsub(".",{["+"]="d[p]=d[p]+1;",["-"]="d[p]=d[p]-1;",[">"]="p=p+1;",["<"]="p=p-1;",["."]="io.write(string.char(d[p]))",[","]="d[p]=string.byte(io.read())",["["]="while d[p]~=0 do ",["]"]="end;"}))()')

두 버전 모두 30000 바이트의 데이터를 추가합니다. 내 두 번째 버전은 입력 / 출력을 기반으로합니다 : '.'뒤의 모든 것 또는 ','가 제거됩니다. 두 번째 버전에서는 무한 루프 ([.,], [] 등)를 허용하지 않습니다.

내 아이디어는 :

print("Hello world!"..string.char(string.byte(io.read())+1)

추가 ', +'를 입력하여 입력하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.