2008年4月14日

[ruby-list:44827] 計算するハッシュ

5.5 です。こんなこと考えました。

Ruby の Hash#new でブロックを与えるのは,

Hash.new{|hash, key| hash[key]=[]}

のように,「デフォルト値を設定したいけど,同一オブジェクトでは困る」
という場合が多いと思います。


しかし,ブロックをもっと積極的に使えば,たとえば以下のように i 番目
の素数を返すハッシュを定義することができます。

PRIME_NUMBERS=Hash.new do |hash, index|
if index<3
hash.update({1=>2, 2=>3})
hash[index]
else
i_max=hash.size
if i_max+1==index
n=hash[i_max]+2
loop do
is_prime=(2..i_max).each do |i|
p_i=hash[i]
break false if n%p_i==0
break true if n<p_i**2
end
break(hash[index]=n) if is_prime
n+=2
end
else
(i_max+1...index).each{|i| hash[i]}
hash[index]
end
end
end

puts PRIME_NUMBERS[93774] # => 12121

このようなハッシュは,“連想記憶”というより“キャッシュ付き関数”
とでも呼びたい感じですね。
(“フィルムカメラ”と“レンズ付きフィルム”みたいな関係?)

ハッシュ生成時に与えるブロックは,もはやデフォルト値を与えるとい
う職務を超え,〈知らないキー〉に対する値を泥縄で計算させるものと
見ることもできそうです。(訊かれて慌てて考える,みたいな)

「で,それが何か?」とツッコまれると困るのですが,Ruby のブロック
の威力を示す例になってるかな,と素人なりに思いまして。

ちなみに,上記の PRIME_NUMBERS は,Ruby 1.8 の Prime よりも格段に
速く,ある程度大きな素数になってくると,Ruby 1.9 の Prime よりもさ
らに速いです。

--
5.5@xxxxx

投稿者 xml-rpc : 2008年4月14日 23:27
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/72090
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。