2010-05-24
パターンマッチの続き
|まめめもでku-ma-meさんがパターンマッチを使って面白そうなことをしておられるので、私もやってみました。
http://d.hatena.ne.jp/ku-ma-me/20100522/p1
やっぱり実践的な使い方をするといろいろ問題点が出てきて良いですね。最新版のプログラム(matcher.rb)です。 http://gist.github.com/372413
足し算をやってみました。
require 'matcher.rb' mat = Matcher.new mat.pattern([Quote::quote(:Sum), :left, :right]) {|hash| mat.match(hash[:left]) + mat.match(hash[:right]) } mat.pattern([Quote::quote(:Const), :value]) {|hash| hash[:value] } p mat.match([:Sum, [:Sum, [:Const, 1], [:Const, 2]], [:Sum, [:Const, 3], [:Const, 4]]])
赤黒木です。一度パターンをコンパイルしたら次回からコンパイルしないでコンパイル済みのコードを再利用しているのですが、赤黒木の例ではパーターンマッチ後の動作を定義するブロック(クロージャ)で外の環境のローカル変数を参照しているのでうまく再利用が効きません。そのためとても効率が悪いです。クロージャをちゃんと更新するようにするのが今後の課題です。
require 'matcher' module RedBlackTree include Quote def insert(x, t) a = insert0(x, t) a = a.dup a[0] = :B a end def insert0(x, t) inspat = Matcher.new inspat.pattern([]) {|hash| [:R, [], x, []] } inspat.pattern([quote(:B), :a, :y, :b]) {|hash| case when x < hash[:y]; balance(insert0(x, hash[:a]), hash[:y], hash[:b]) when x > hash[:y]; balance(hash[:a], hash[:y], insert0(x, hash[:b])) else t end } inspat.pattern([quote(:R), :a, :y, :b]) {|hash| case when x < hash[:y]; [:R, insert0(x, hash[:a]), hash[:y], hash[:b]] when x > hash[:y]; [:R, hash[:a], hash[:y], insert0(x, hash[:b])] else t end } inspat.match(t) end def member(x, t) mempat = Matcher.new mempat.pattern([[Symbol, :col], :a, :y, :b]) {|hash| case when x<hash[:y]; member(x, hash[:a]) when x>hash[:y]; member(x, hash[:b]) else true end } mempat.pattern([:dmy]) {|hash| false } mempat.match(t) end def balance(l, v, r) balpat = Matcher.new matexc = lambda {|hash| [:R, [:B, hash[:a], hash[:x], hash[:b]], hash[:y], [:B, hash[:c], hash[:z], hash[:d]]] } balpat.pattern([[quote(:R), [quote(:R), :a, :x, :b], :y, :c], :z, :d], &matexc) balpat.pattern([[quote(:R), :a, :x, [quote(:R), :b, :y, :c]], :z, :d], &matexc) balpat.pattern([[quote(:R), :a, :x, :b], :y, [quote(:R), :c, :z, :d]], &matexc) balpat.pattern([:a, :x, [quote(:R), [quote(:R), :b, :y, :c], :z, :d]], &matexc) balpat.pattern([:a, :x, [quote(:R), :b, :y, [quote(:R), :c, :z, :d]]], &matexc) balpat.pattern([:a, :x, :b]) {|hash| [:B, hash[:a], hash[:x], hash[:b]] } balpat.match([l, v, r]) end end include RedBlackTree tree = [] (1..10).to_a.shuffle.each do |x| tree = insert(x, tree) end p member( 5, tree) #=> true p member(11, tree) #=> false p member( 0, tree) #=> false p tree
コメントを書く
トラックバック - http://d.hatena.ne.jp/miura1729/20100524/1274695704
リンク元
- 12 http://llvmruby.org/wordpress-llvmruby/
- 12 http://www.google.co.jp/search?q=RFC1213&ie=utf-8&oe=utf-8&aq=t&hl=ja&client=firefox-a&rlz=1R1GGGL_ja___JP365
- 11 http://d.hatena.ne.jp/kwatch/20080304/1204646782
- 10 http://www.google.co.jp/hws/search?hl=ja&q=RFC1213&client=fenrir&adsafe=off&safe=off&lr=lang_ja
- 9 http://d.hatena.ne.jp/
- 9 http://www.google.co.jp/search?client=opera&rls=ja&q=RFC1213&sourceid=opera&ie=utf-8&oe=utf-8&lr=lang_ja
- 9 http://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4ACGW_jaJP329JP339&q=文字 処理 遅い
- 8 http://d.hatena.ne.jp/mirichi/20100616/p1
- 8 http://www.google.co.jp/search?hl=ja&source=hp&q=RFC1213&aq=f&aqi=g4&aql=&oq=&gs_rfai=
- 8 http://www.google.co.jp/search?q=ランダムテストとは&hl=ja&rlz=1T4GGLL_jaJP348JP349&sa=2