コラッツの予想(角谷の問題)

プログラミング甲子園のコーナーで取り上げられていたのをやってみる。
本来の使用言語にRubyはないけど気にしない。

#for backward than Ruby1.9
module Kernel
  unless respond_to?(:tap)
    def tap
      yield(self) ; self
    end
  end
end



class Integer
  def even?
    self < 1 and raise RangeError, 'out of defined range'
    (self % 2).zero?
  end
  
  def collatz
    even? ? self / 2 : self * 3 + 1
  end
end



def collatz_sequence(n)
  [].tap{|seq| seq.push(n = n.collatz) until n == 1 }
end


def do_collatz(f)
  f.readlines.map{|line| line.to_i }.tap do |data|
    puts data[0...data.index(0)].map{|n| collatz_sequence(n).size }
  end
end


do_collatz($stdin)