遅延評価
lambdaを使えば遅延評価が出来ると知ったので,たらい回し関数でテストしてみる.たらい回し関数は青木日記 2003-03-15から持ってきた.
def tarai( x, y, z ) if x <= y then y else tarai(tarai(x-1, y, z), tarai(y-1, z, x), tarai(z-1, x, y)) end end p tarai(12, 6, 0) #=> 12
まじめに計算すると10秒掛かる.
class Lazy def initialize(&block) @val,@block = nil, block end def val @val ||= @block.call() end end def lazy(&block); Lazy.new(&block); end def lazy_tarai(ax,ay,az) f = lambda {|x,y,z| if x <= y y else f[ f[ x-1, y, lazy{z.val}], f[ y-1, z.val, lazy{x} ], lazy{f[ z.val-1, x, lazy{y} ]}] end } f[ax,ay, lazy{az}] end p lazy_tarai(120, 60, 0) #=> 120
12だと一瞬で終わるので,120でテスト.それでも0.7秒程度.
本当ならx,yもlazyにするんだろうけど,必ず最初に評価されるので,lazyにする意味はないと思って,zのみ遅延評価するようにしてみた.
追記:
青木日記 2003-03-23
青木日記 2003-04-11
青木日記 2003-04-20
青木日記 2003-04-25
一番最後のバージョンをうちで実行したら,120で0.01秒….すごすぎ.