2014-02-19
■[Ruby] 放射線耐性 Quine (1 文字消しても動く Quine)
放射線はメモリエラーを引き起こすらしいです。そんな放射線が飛び交う過酷な環境でも、できることなら Quine したい。
ということで、プログラム内の 1 文字をランダムに消しても元のプログラムを出力する、なんともロバストな Quine を書きました。*1
何を言っているかわからないと思いますが、こんなふうに動くものです。
# ランダムに 1 文字消すスクリプト $ cat mutate.rb src = $<.read src[rand(src.size), 1] = "" print src # rrquine.rb からランダムに 1 文字消したプログラムを生成する $ ruby mutate.rb rrquine.rb > broken.rb # 壊れたプログラムを実行する (!) $ ruby broken.rb > rrquine2.rb # 元に戻る (!!) $ diff rrquine.rb rrquine2.rb # 一致!
正直書けるわけないと思ってましたが、なんと書けてしまった。Ruby 恐ろしいなあ。他に書ける言語があるだろうか。*2
以下コード。もっと賢い方法があったら教えてください。
"%\ #{at_exit{eval'(eval q=%(s=%(B%A C{at_exit{ZGQG##G }}}ABB.rescue x rescue 42##B Z=GQG##G instance_Z=GQG##G Z Z if Z==instance_Z ).gsub ?Z,%[eval] 7.times{|n|s.gsub! (n+65).chr,(n<1?92:n+33).chr} puts s.gsub ?Q,%[(eval q=%(]+q+%[))#] $stdout.flush exit!0))#'##' }}}\"".rescue x rescue 42##" eval='(eval q=%(s=%(B%A C{at_exit{ZGQG##G }}}ABB.rescue x rescue 42##B Z=GQG##G instance_Z=GQG##G Z Z if Z==instance_Z ).gsub ?Z,%[eval] 7.times{|n|s.gsub! (n+65).chr,(n<1?92:n+33).chr} puts s.gsub ?Q,%[(eval q=%(]+q+%[))#] $stdout.flush exit!0))#'##' instance_eval='(eval q=%(s=%(B%A C{at_exit{ZGQG##G }}}ABB.rescue x rescue 42##B Z=GQG##G instance_Z=GQG##G Z Z if Z==instance_Z ).gsub ?Z,%[eval] 7.times{|n|s.gsub! (n+65).chr,(n<1?92:n+33).chr} puts s.gsub ?Q,%[(eval q=%(]+q+%[))#] $stdout.flush exit!0))#'##' eval eval if eval==instance_eval
- 92 http://t.co/TJT35H8AT7
- 34 https://www.facebook.com/
- 32 http://pipes.yahoo.com/pipes/pipe.info?_id=e4c70514b5136c08ae93591f390be2e2
- 24 http://t.co/5b5dwejXsU
- 22 http://t.co/5m05q9IWs0
- 20 http://t.co/ocq9vl61xH
- 14 http://b.hatena.ne.jp/
- 14 http://t.co/SFKBnKNxXY
- 12 http://b.hatena.ne.jp/entrylist
- 10 http://t.co/QHeMHc39bJ