パスカルの三角形リトライ
やっぱり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のリファレンスマニュアルを見なくなったなぁ.コレは良い傾向なのか?しかし自分の知っている事だけで済まそうとするから,コードがゴチャゴチャしそうで駄目だなぁ.
「こーゆーメソッドは既にあるかも」ってすぐにリファレンスマニュアルを探すぐらいの器量が無いと,良いコードは書けないのかもしれん.