A 3rd-order Quine: Haskell -> Python -> Ruby

我曾经在我的 Wiki 笔记 中介绍过 Quine ,就是能打印自身的程序。今天在这里看到一个很厉害的 Quine :

q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']
main=q "q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']" "def q(a,b,c):print b+chr(10)+'q('+repr(b)+','+repr(c)+','+repr(a)+')'" "def e(x) return 34.chr+x+34.chr end;def q(a,b,c) print b+10.chr+'main=q '+e(b)+' '+e(c)+' '+e(a)+' '+10.chr end"
这是一个 Haskell 程序,运行它会输出一个 Python 程序,再运行这个 Python 程序会输出一个 Ruby 程序,再运行这个 Ruby 程序会得到一个 Haskell 程序,对了!就和最开始那个 Haskell 程序一模一样的! :D

Comments (4)

quark February 12, 2008

这个很有难度啊~

记得以前同济大学的OJ上有一题就是输出程序的源代码。 不是十分难,自己琢磨下也就独立完成了(换本本了,源代码找不到了 -.-)。

quark February 15, 2008
今天把原来的本本硬盘翻出来,找到了TOJ1072.pas,放在这里做个记号:)

var s:array [1..9] of string;z:string;i,p,t:integer;
begin
s[1]:='var s:array [1..9] of string;z:string;i,p,t:integer;';
s[2]:='begin';
s[3]:='for i:=1 to 2 do writeln(s[i]);';
s[4]:='for i:=1 to 9 do begin p:=1;z:=s[i];';
s[5]:='while p>0 do begin t:=pos('''''''',copy(z,p,maxint));';
s[6]:='if t>0 then begin p:=p+t+1;insert('''''''',z,p-1) end else p:=0 end;';
s[7]:='writeln(''s['',i,'']:='''''',z,'''''';'') end;';
s[8]:='for i:=3 to 9 do writeln(s[i]);';
s[9]:='end.';
for i:=1 to 2 do writeln(s[i]);
for i:=1 to 9 do begin p:=1;z:=s[i];
while p>0 do begin t:=pos('''',copy(z,p,maxint));
if t>0 then begin p:=p+t+1;insert('''',z,p-1) end else p:=0 end;
writeln('s[',i,']:=''',z,''';') end;
for i:=3 to 9 do writeln(s[i]);
end.
pluskid February 16, 2008
@quark:
上次 MSTC CFF(Coding For Fun) 有这么一道题目:写一个程序,源代码的整体形状要看上去像一个字母“M”,就是代码的排版了,这个程序编译运行之后可以输出另外一个程序的代码,这段代码要看上去像一个“S”字母,类推是“T”和“C”,最后这个“C”要能编译运行再输出和原来一模一样的那个“M”字来。最后是以代码字数最少为胜。挺有意思的。我当时也做了一个,虽然俱乐部内部人员不能参加这个比赛,不过即使参加也没能排上前三,当时有不少精彩的作品呢。
quark February 16, 2008
@pluskid:
我想,用brainfuck语言来写会比较容易排版^_^