「パスカルの三角形」というのはこういうやつですね。
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
この出力を目標に、Haskell で書いてみます。
以前に 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)}
簡潔ですね。これを手本にしてみます。
こんな感じでしょうか。
main :: IO () main = putStr $ unlines $ map (centering 30 . toString) (map pascal [0..7]) centering :: Int -> String -> String centering n str = (replicate i ' ') ++ str ++ (replicate j ' ') where l = length str i = div (n - l) 2 j = n - l - i toString :: [Int] -> String toString xs = tail $ concat $ map f xs where f x = ' ': show x pascal :: Int -> [Int] pascal 0 = [1] pascal n = [1] ++ eachCons (pascal (n - 1)) ++ [1] eachCons :: [Int] -> [Int] eachCons xs = if length xs < 2 then [] else (head xs + (head . tail) xs): (eachCons . tail) xs
いやー、これだけでも悩みましたよ。
関数 pascal と eachCons は Ruby の動作とまったく同じです。あとは関数 toString と centering で結果を成形された文字列にしています。
ちなみに、
- unlines 関数:[String]を改行を入れて結合する。[String] -> String。
- concat 関数:リストの平坦化。
- div 関数:整数/整数をして整数で返す。
です。
初心者が気づいたこと。
- 作者: Miran Lipovača,田中英行,村主崇行
- 出版社/メーカー: オーム社
- 発売日: 2012/05/23
- メディア: 単行本(ソフトカバー)
- 購入: 25人 クリック: 580回
- この商品を含むブログ (73件) を見る