続・パスカルの三角形
というわけで、昨日話題を振ったパスカルの三角形の Enumerable 活用版です。
ruby -e '(0..9).map {|k| (1..k).inject([1]) { |a,dummy| (a + [0]).inject([0,[]]) { |(prev, li),x| [x, li + [prev + x]] }[1] } }.each {|l| p l}'
もしくは、中間結果をきちんと最後まで持ってくるようにして、
ruby -e '(1..9).inject([[1]]) { |a,dummy| a << (a[-1] + [0]).inject([0,[]]) { |(prev, li),x| [x, li + [prev + x]] }[1] }.each {|l| p l}'
実行結果は
[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] [1, 8, 28, 56, 70, 56, 28, 8, 1] [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
畳込み関数 (inject) は偉大なり。
今回は畳込みは右か左かはあんまり関係ないのですが、a[-1] + [0] とかやっているのは、本当のリスト処理の思想からするとダメダメですね……。
シンプルさを求めるなら
ruby -e '(0..9).map {|k| (1..k).inject([1]) { |a, dummy| ([0] + a).zip(a + [0]).map {|x, y| x + y} } }.each {|l| p l}'
リストの末尾に concat するのがお嫌いなら、
ruby -e '(0..9).map {|k| (1..k).inject([1]) { |a, dummy| ([0] + a).zip(a).map {|x, y| y ? x + y : x} } }.each {|l| p l}'