nekoTheShadow’s diary

IT業界の片隅でひっそり生きるシステムエンジニアです(´・ω・`)

Hash.new{}を有効活用してみたい。

rubyHashクラスのクラスメソッドnewは引数にブロックをとることができることはよく知られています。

hash = Hash.new do |hash,key|
  if key.even?
      val = "奇数"
  else # key.odd?
      val = "偶数"
  end
  hash[key] = val
end

p hash[1] #=> "偶数"
p hash    #=> {1=>"偶数"}
p hash[2] #=> "奇数"
p hash    #=> {1=>"偶数", 2=>"奇数"}

これを何とか有効活用できないかと小一時間ほど考えたのですが……
思いつきませんでした(´・ω・`)

せいぜい思いついたのは、フィボナッチ数列ぐらい。

fib = Hash.new do |fib,key|
  if key == 0 || key == 1 
      fib[key] = key
  else
      fib[key] = fib[key-1] + fib[key-2]
  end
end

p fib[9]  #=> 34
p fib     #=> {1=>1, 0=>0, 2=>1, 3=>2, 4=>3, 5=>5, 6=>8, 7=>13, 8=>21, 9=>34}
p fib[7]  #=> 13
p fib[10] #=> 55
p fib     #=> {1=>1, 0=>0, 2=>1, 3=>2, 4=>3, 5=>5, 6=>8, 7=>13, 8=>21, 9=>34, 10=>55}

上記の例では、再帰とメモ化が同時に組み込まれています。

まあ、これでも十分に使えているといえばその通りなのですが、もっと、こう――「これしかない」という使い方がしたいのです。
もちろん、「選択肢はこれだけ。否が応でも使うほかない」という状況はもちろんのこと、「使わないと計算量が何倍にも増える。オーバーフローする」というような状況で、びしっと決めてみたい。
日を改めて思いつきましたら、ブログに書いてみようと思います。