パスカルの三角形とは、こんな感じのものです。
1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 1 6 15 20 15 6 1 1 7 21 35 35 21 7 1
規則性がわかりますね。多項式 (a + b)n を展開すると、係数がこんな風に並びます。
Ruby で関数型プログラミングっぽく書いてみました。結構きれいに書けます。
pascal = ->(n) { each_cons = ->(ar) { (ar.size < 2) ? [] : [ar[0] + ar[1]] + each_cons.(ar.drop(1)) } n.zero? ? [1] : [1] + each_cons.(pascal.(n - 1)) + [1] } n = 8 n.times {|i| puts pascal.(i).join(" ").center(30)}
追記(2020/1/7)
Enumerator を使って。
def generate_pascal_triangle Enumerator.new do |y| y << [1] ary = [1, 1] loop do y << ary ary = [1] + ary.each_cons(2).map { |a, b| a + b } + [1] end end end n = 8 puts generate_pascal_triangle.take(n).map { |ary| ary.join(" ").center(30) }
パターンマッチを使って。
def calc_pascal_triangle(*args) case args in [1] then [[1]] in [2, Array => result] then result in [Integer => n] calc_pascal_triangle(n, [[1], [1, 1]]) in [Integer => n, Array => result] ary = [1] + result[-1].each_cons(2).map { |a, b| a + b } + [1] calc_pascal_triangle(n - 1, result + [ary]) end end n = 8 puts calc_pascal_triangle(n).map { |ary| ary.join(" ").center(30) }
パターンマッチ、意外とおもしろいな。無理やりだけれども、型記述や多重ディスパッチみたいなことも可能かも。Ruby に合うかどうかはわからないが。