写一个头脑翻译


18

在任何编程或脚本语言X,写一个程序,需要一个有效的brainfuck源代码从标准输入和输出,标准输出,程序的源代码,写的语言X,这将输出同样的事情作为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
您可能想添加一个条款,使目标语言也不要动脑子;)
Josh

@Josh好吧,如果有人设法编写了一个简短的Brainfuck程序,该程序删除了不必要的无用代码,为什么不让他们这样做呢?
user12205 2014年

2
好吧,很简单,因为输出源不变的琐碎解决方案对于脑力劳动来说反而会得分很低。如果另一种语言能胜过我,我会感到惊讶。
Tim Seguine 2014年

@Tim Seguine我可以更改问题,但这对已经提供答案的人不公平吗?如果我改变了这个问题,我正在考虑改变分数计算,是否byte count of source + (byte count of output)^2会鼓励人们更多地专注于简化输出?
user12205 2014年

通常,在回答之后改变这样的问题是令人讨厌的。我只是在指出我认为乔希是正确的原因。最好先在沙箱中发布这样的内容,这样您就可以解决潜在的问题,同时对所有人公平。
Tim Seguine 2014年

Answers:


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个字节,每个选项一个。首先,将八个命令中的每一个都转换为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 2014年

我认为wv.*?(?=w)是错的。我认为它只会删除下一个代码],但是您需要它来找到匹配的代码 ];您需要注意嵌套操作...
Timwi 2014年

@Timwi通过忽略嵌套的case来修复,该嵌套的case wv[^v]*(?=w)比替代方法要短得多。
primo 2014年

14

Brainfuck,5 + 540 = 545字节

5个字节的代码,从给定测试文件的输出中得到540个(假设从我粘贴的代码中得到正确的计数)。

,[.,]

假设EOF为0。


@primo,因为它在读取解释器时不会复位,该解释器不会更改EOF处的值,因此对于所有大于0字节的输入,此程序将成为无穷循环。
Sylwester

我不禁想知道,什么软件用来运行这些东西?xD
Teun Pronk 2014年

@TeunPronk有一个叫做bfigithub.com/susam/bfi)的头脑解释器。只需编译并安装它,然后像这样运行即可:要解释的Brainfuck文件bfi input.bf在哪里input.bf
Braden Best 2014年

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运行)。请记住要对输入内容进行网址转义!

这样做基本上是这样的-如果BF脚本包含“,”,它将作为嵌入了$ b = 1的结果脚本进行嵌入。在顶部。如果它不包含“,”,则将其优化到“ echo'<BF output>'”。方便地,OP中的测试脚本不需要任何输入。addlashes()仅用于转义'和\。


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

Python-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

1

操脑,109 + 407 = 516

>+[>+++++++[-<------>]<-[-[-[-[--------------[--[>+++++[-<------>]<+[--[[-]<[-]>]]]]]]]]<[.[-]]>>,[-<+<+>>]<]

在线尝试!

它仅删除非BF操作,而不查看其他优化。


0

Lua-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

Lua-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)..")")

Lua-376 + 366 = 742

这个版本是为了证明lua可以比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)

从您的输入中,加上一个额外的“,+”。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.