鍋あり谷あり

テーマを決めずに適当に書いています。

コラッツ

http://jijixi.azito.com/cgi-bin/diary/index.rb?date=20060711#p02
経由で、
http://ll.jus.or.jp/2006/blog/doukaku2

class Collatz 
  include Enumerable
  def initialize( n )
    @n=n
    @cache={1=>1}
  end

  def calc(n)
    @cache[n]=_calc(n) unless @cache.include?(n)
    @cache[n]
  end
  
  def _calc(n)
    return 1+calc( 0==n%2 ? n/2 : n*3+1 )
  end

  def each
    (1..@n).each{ |n|  yield [n,calc(n)]  }
  end
end

p Collatz.new(100).max{ |a,b| a[1]<=>b[1] }[0]

書いてみた。
初めて Enumerable なクラスを作ったような気がする。ruby はよく書くんだが、オブジェクト指向方面の機能をほとんど使ってないなぁと改めて思う。
無駄に長いような気がしてならない(最初にアップしたときと比べると数行短くなっているが)。
_calc を calc の中に書くと短くなるか。うーむ。
キャッシュは、n について計算しているときに n/2 未満を捨てるというコードを入れるとメモリ使用量が減ると思う。そうは書いてないが。
スタックオーバーフローがちょっとこわいが、出題が N=100 だし、どんまいということで。

速くなる工夫とか軽くなる工夫とか、そんなのは全然してない。偶数ぐらいとばした方が良かったか。あ。一応キャッシュはしてる。