パスカルの三角形リトライ

やっぱりb2oxさんは凄いと思うんだ.昨日コメント欄に書いていてくれたコード,コメントだとインデントされず,見にくいので,記事に書いてみました.


個人的に感動したget_atの部分を.

def get_at(h)
  return nil unless h.is_a?(Integer)
  return nil if h < 1
  return @triangle[h-1] unless @triangle[h-1].nil?
  1.upto(h-1){|i|
    next unless @triangle[i].nil?
    pt = @triangle[i-1]
    px = [0] + pt
    pt.each_with_index{|v,j| px[j] += v }
    @triangle[i] = px  
  }
  return @triangle[h-1]
end

しかし,本当によくこんな計算方法を思いつくものだなぁ.案外普通に思いつくもんなのかな.あ,そうか頭が固いんだ俺は.


それではパスカルの三角形・組み合わせ計算ver.をします.またソースコードばかりになってしまった.

class Pascal
  def initialize(height = 1, top = 1)
    if height.is_a?(Integer) and height > 0
      @height = height
    else
      @height = 1
    end
    
    @top = top.is_a?(Integer) ? top : [1]
    @triangle = []
    @triangle[0] = [@top]
    self.triangle
  end
  
  attr_reader :height ,:top
  
  def triangle
    (0 .. (@height - 1)).each{ |i|
      @triangle[i] = col i
    }
    @triangle
  end

  def col(height)
    col = []
    (0 .. height).each{|i|
      col << @top * combination(height,i)
    }
    col
  end
  
  def combination(n,k)
    factrial(n) / ((factrial k) * (factrial(n - k)))
  end
  
  def factrial(x)
    return 1 if x  < 2
    x * factrial(x - 1)
  end
  
  def top=(top)
    @top = top.is_a?(Integer) ? top : 1
    @triangle[0] = [top] 
    self.triangle
  end
  
  def height=(height)
    if height.is_a?(Integer) and height > 0
      @height = height
    else
      @height = 1
    end
    self.triangle
  end
  
  def p_triangle
    @triangle.each do |e|
     p e
    end
  end
end

こうすると,colでその行を得ても,@triangleが変更されないですむ.しかし,なんていうか,長過ぎ.セッタなんて初めて書いたよ.あれだ,オブジェクト指向の勉強だと思えば良いか.
実行結果は,気になる人だけこのソースをコピペして,irbやらで適当の遊んでください.


組み合わせ計算が,思いのほか綺麗に書けて嬉しい.まぁ割と多機能?使い道無いよ.しかもスッキリではない.まぁ楽しいので良しとするか.


最近,Rubyのリファレンスマニュアルを見なくなったなぁ.コレは良い傾向なのか?しかし自分の知っている事だけで済まそうとするから,コードがゴチャゴチャしそうで駄目だなぁ.
「こーゆーメソッドは既にあるかも」ってすぐにリファレンスマニュアルを探すぐらいの器量が無いと,良いコードは書けないのかもしれん.