入門 超絶技巧プログラミング !

21
入門 超絶技巧プログラミング ひげ 2016.1.24

Transcript of 入門 超絶技巧プログラミング !

入門 超絶技巧プログラミング

ひげ

2016.1.24

超絶技巧プログラミング「実践的な言語を使って全く実践的でないモノを作る遊び」

アスキーアート + Quineの話です(とても面白かった)この本

例: 地球が回る?(遠藤さんが作ったやつ)http://d.hatena.ne.jp/ku-ma-me/?of=12https://github.com/mame/trance-book/tree/master/1-1-1v=0000;eval$s=%q~d=%!^Lcf<LK8, _@7gj*LJ=c5nM)Tp1g0%Xv.,S[<>YoP 4ZojjV)O>qIH1/n[|2yE[>:ieC "%.#% :::##" 97N-A&Kj_K_><wS5rtWk@*a+Y5 yH?b[F^e7C/56j|pmRe+:)B "##% ::##########" O98(Zh)'Iof*nm.,$C5Nyt= PPu01Avw^<IiQ=5$'D-y? "##: ###############" g6`YT+qLw9k^ch|K'),tc 6ygIL8xI#LNz3v}T=4W "# #. .####:#######" lL27FZ0ij)7TQCI)P7u }RT5-iJbbG5P-DHB<. " ##### # :############" R,YvZ_rnv6ky-G+4U' $*are@b4U351Q-ug5 " #######################" 00x8RR%`Om7VDp4M5 PFixrPvl&<p[]1IJ " ############:#### %#####" EGgDt8Lm#;bc4zS^ y]0`_PstfUxOC(q " .#############:##% .## ." /,}.YOIFj(k&q_V zcaAi?]^lCVYp!; " %% .################. #. " ;s="v=%04o;ev"% (;v=(v-($*+[45, ":####: :##############% : " ])[n=0].to_i;)% 360)+"al$s=%q#{ "%######. ######### " ;;"%c"%126+$s<< 126}";d.gsub!(/ "##########. #######% " |\s|".*"/,"");; require"zlib"|| "########### :######. " ;d=d.unpack"C*" d.map{|c|n=(n|| ":#########: .######: . " )*90+(c-2)%91}; e=["%x"%n].pack " :#######% :###### #: " &&"H*";e=Zlib:: Inflate.inflate( " ######% .####% :: " &&e).unpack("b*" )[0];22.times{|y| " ####% %### " ;w=(Math.sqrt(1-( (y*2.0-21)/22)**(; " .###: .#% " ;2))*23).floor;(w* 2-1).times{|x|u=(e+ " %## " )[y*z=360,z]*2;u=u[ 90*x/w+v+90,90/w];s[( " #. " ;y*80)+120-w+x]=(""<< 32<<".:%#")[4*u.count(( " . " ;"0"))/u.size]}};;puts\ s+";_ The Qlobe#{" "*18+ ( "# :#######" ;"Copyright(C).Yusuke End\ oh, 2010")}";exit~;_ The Qlobe Copyright(C).Yusuke Endoh, 2010

アスキーアート「プレーンテキストによる視覚的表現技法のコト」(wikipedia)

コードをアスキーアート化空白と改行がソースコード中に入れ放題であると楽!

つまり次の3つの条件が当てはまる言語だと楽 (そうでない場合は頑張る)

eval が使える

空白がなくてもプログラミング可

文字列の空白除去が簡単

例えばRubyでは

puts "Hello,World!"

をアスキーアート化するためには

eval(%w(puts "Hello,World!")*"")

やってみた

eval (%w( 3.ti mes{ pu t s " He l lo % cI G GG "% [ 3 2 ] } # ###N obut ada) *"")

実は...こういうコードで自動整形している

asciiart = <<END #### #### #### #### ## # # # ## # ## # ## # ## ## # # # # # # #### #### #### #### END code = <<'END' 3.times { puts "Hello%cIGGG" % [32] } #### Nobutada END code = 'eval(%w(' + code.split.join + ')*"")' puts asciiart.gsub('#') { code.slice!(0,1) }

Quine自己生成プログラミング

コードと実行結果が等価なプログラム

名前の由来は「間接的な自己言及」の研究をした哲学者

から

「この文は偽である」(直接的な自己言及)

Quineコードを書く(Rubyでは)

puts ...

putsと出力したいので...

puts "puts "puts ... " " "

無限ループ! なので出力したい文字を変数に代入

s = "s = \" ... puts s\"; puts s"; puts s

無限ループ!

置換を使うirb> s="s=\"...\";puts(s.sub(\"...\", s))";puts(s.sub("...", s)) s="s="...";puts(s.sub("...", s))";puts(s.sub("...", s))

おしい! エスケープ処理

irb> s="s=...;puts(s.sub(\"...\", s))";puts(s.sub("...", s.dump)) s="s=...;puts(s.sub(\"...\", s))";puts(s.sub("...", s.dump))

evalを利用すれば重複を減らせる

eval s = "puts 'eval s = ' + s.dump"

要するに置換とエスケープ処理でできる

2つを合わせる本に載ってた四角いQuine (コメントは消さないと動かない

よ、たぶん)

eval$s=%w( s = %(eval$s=%w(#{$s})*""); f = -> n{s.slice!(0,n)}; puts(f[32]); # ここからが整形処理 14.times {|i| puts(f[2] + 32.chr * 28 + f[2]) }; puts(s) ;; # パティング )*""

自分でも作ってみた

コイツを

二値化して(適当なwebサイトとエディタを使って)

(Haskellなんかを使って)コードを書いて

import Data.List (intercalate, group) main = getContents >>= putStrLn . unlines . count . lines count = map (toRuby . zip [1..] . map length . group) toRuby = (\s -> "puts(" ++ s ++ ");") . intercalate "+" . map f where f = \(i,l) -> if odd i then "f["++show l++"]" else "32.chr*"++show l

ランレングス圧縮して

四角Quineと入れ替えて(パティング適当...)

eval$s=%w( s = %(eval$s=%w(#{$s})*""); f = -> n{s.slice!(0,n)}; puts(f[150]); puts(f[74]+32.chr*3+f[73]); . . puts(f[150]); ################################################################################ . . ################################################################################ ############################ ---Quine-IGGG-LOGO--2016.1.24--Matsubara-Nobutada--- ############################################ )*""

実行できた

再実行できた!

おしまい