#overlappingPairsCollect: を使ってパスカルの三角形


巷ではなにやら、風変わりな方法でパスカルの三角形を得るのが流行っているようなので、便乗して id:sumim:20060517#p1 で見つけた #overlappingPairsCollect: を使ってみました。

| results |

results := OrderedCollection with: #(1).
10 timesRepeat: [
   results add: (#(0), results last, #(0) overlappingPairsCollect: [:aa :bb | aa + bb])].

World findATranscript: nil.
results do: [:line | Transcript cr; show: line]
#(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)
#(1 10 45 120 210 252 210 120 45 10 1)


結果の前後に 1 を付ける版。

| results |

results := OrderedCollection with: #(1).
10 timesRepeat: [
   results add: (#(1), (results last overlappingPairsCollect: [:aa :bb | aa + bb]), #(1))].

World findATranscript: nil.
results do: [:line | Transcript cr; show: line]


悪ノリして #streamContents: 版。

| results |

results := Array streamContents: [:resultsStream |
   resultsStream nextPut: #(1).
   10 timesRepeat: [
      resultsStream nextPut: (
         Array streamContents: [:ss |
            ss nextPut: 1.
            ss nextPutAll: (resultsStream last overlappingPairsCollect: [:aa :bb | aa + bb]).
            ss nextPut: 1])]].

World findATranscript: nil.
results do: [:line | Transcript cr; show: line]

追記
この #overlappingPairsCollect: と似たようなことを Haskell の zipWith でも、その引数を工夫して記述することで実行可能なことから、無限数列版パスカルの三角形の定義を思いついたので、結城浩のHaskell日記 - パスカルの三角形 のコメント欄にお邪魔させていただいたのですが、その後 nobsun により、よりスマート、かつ、ずっと前に公開されていた Hanatani さん版の存在が…。 よくよく見れば、むしろ最初に思いついたのより Hanatani さん版のほうが、上のスクリプトの考え方に近いということに気づいて、ダブル orz 。w

pascal = [1] : [ zipWith (+) ([0] ++ xs) (xs ++ [0]) | xs <- pascal ]

うーん。美しい…。