`
swordz
  • 浏览: 12899 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

各种各样的 Ruby Quine

    博客分类:
  • ruby
阅读更多

Quine就是输出自身的程序,最早源自Ken Thompson 的一篇论文。

以后各种程序设计语言都会玩这个游戏。

Ruby以灵活著称,Quine能玩出多少花样呢?我收集了不少,研究这些代码一个是好玩,一个也能加深对RUBY理解。

printf(s = 'printf(s = %c%s%c, 39, s, 39)', 39, s, 39)

 

s="s=%c%s%c; printf s,34,s,34,10%c"; printf s,34,s,34,10

 

以上这两个是对C语言QUINE的直接改编,相对好理解。

a= <<'EOF'
print "a=<<'EOF'"
print a
print "EOF\n"
print a
EOF
  print "a=<<'EOF'"
  print a
  print "EOF\n"
  print a

 

这个利用了HERE的语法特点,也好理解。

def x(s); puts %Q{#{s} x(%q{#{s}})}; end; x(%q{def x(s); puts %Q{#{s} x(%q{#{s}})}; end;})

 

这个不好懂,改编自一个LISP QUINE,应该是用到函数式程序的特点吧。

(lambda (x) (list x (list (quote quote) x))) (quote (lambda (x) (list x (list (quote quote) x)))))

 一个非常简单的,但却没懂

puts <<2*2,2
puts <<2*2,2
2

 

非常CUTE,但查了<<用法,没对,分隔参数的处理讲的太清楚。谁理解了给说一下。

_="_=%p;puts _%%_";puts _%_

 

这个极短,%p用到了str.inspect特性。

x=%q/puts "x=%q\057#{x}\057;#{x}"/;puts "x=%q\057#{x}\057;#{x}"

 

 利用了/ /,#{x}等特性

 再来个长的

$a=%w( def xx
  $a.each do |x| if x =~ /xx/
  print x+"\n" else print x, " " end end end; print "$a=%w( "; xx
  print ")\n"; xx
  )
  def xx
  $a.each do |x| if x =~ /xx/
  print x+"\n" else print x, " " end end end; print "$a=%w( "; xx
  print ")\n"; xx

 来个对称的

a="a=%p\nb=%p\nc=%p\nputs a%%[a,b,c]\nputs c"
b="c=%p\nb=%p\na=%p"
c="puts b%[c,b,a]"
puts a%[a,b,c]
puts c
puts b%[c,b,a]
c="puts b%[c,b,a]"
b="c=%p\nb=%p\na=%p"
a="a=%p\nb=%p\nc=%p\nputs a%%[a,b,c]\nputs c"

 

最后来个比较另类的

require "base64"
class Quine
  def doSomething(operation)
     puts "#{Base64.decode64(operation)}
     encodedBody=\"#{operation}\"
     Quine.new.doSomething(encodedBody)"
    end
end
     encodedBody="cmVxdWlyZSAiYmFzZTY0IgoKY2xhc3MgUXVpbmUKICAKICBkZWYgZG9Tb21l
dGhpbmcob3BlcmF0aW9uKQogICAgIHB1dHMgIiN7QmFzZTY0LmRlY29kZTY0
KG9wZXJhdGlvbil9CiAgICAgZW5jb2RlZEJvZHk9XCIje29wZXJhdGlvbn1c
IgogICAgIFF1aW5lLm5ldy5kb1NvbWV0aGluZyhlbmNvZGVkQm9keSkiCiAg
ICBlbmQKZW5k"
     Quine.new.doSomething(encodedBody)

 

添一个最短的

puts File.read(__FILE__)

 

 

 

 

分享到:
评论
5 楼 swordz 2009-06-28  
puts File.read $0
更短。不过想想这种QUINE失去了本来意义了。变成读文件了。

Hooopo 写道
其实最短的是:
print File.read $0

最长的:
#这里加很长很长很长的无用代码....
print File.read $0


4 楼 Hooopo 2009-06-28  
再根据NS提供的改一下:
 eval DATA.read
__END__
print File.read $0#只能是$0,不能使__FILE__

3 楼 Hooopo 2009-06-28  
其实最短的是:
print File.read $0

最长的:
#这里加很长很长很长的无用代码....
print File.read $0

2 楼 swordz 2009-06-27  
night_stalker 写道
最简单的……
print File.read(__FILE__)

这个高,倒没看到有人想到

这段代码比较 tricky ……
puts <<2*2,2
puts <<2*2,2
2

其实是用 2 做结束符的 here-doc
puts <<2*2,2
puts <<2*2,2
2

第一行的意思是:输出蓝字 *2,然后输出一个 2。

改成这样或许容易明白一些?
puts (<<EOS * 2), 'EOS'
puts (<<EOS * 2), 'EOS'
EOS


1行的 2*2 里的第一个 2 是第2行的意思?第一感觉应该变成4啊
ruby语法还是有比较魔幻的地方
1 楼 night_stalker 2009-06-27  
最简单的……
print File.read(__FILE__)


这段代码比较 tricky ……
puts <<2*2,2
puts <<2*2,2
2

其实是用 2 做结束符的 here-doc
puts <<2*2,2
puts <<2*2,2
2

第一行的意思是:输出蓝字 *2,然后输出一个 2。

改成这样或许容易明白一些?
puts (<<EOS * 2), 'EOS'
puts (<<EOS * 2), 'EOS'
EOS


或者这样理解:
str = <<2
puts <<2*2, 2
2

puts str*2, 2


其中 str * 2 相当于 str + str


str = <<2
xxx
2
相当于 str = "xxx\n"

你觉得比较魔幻,是因为它故意用一堆 2 来混淆视线 ……

相关推荐

Global site tag (gtag.js) - Google Analytics