问题描述
import Data.List (intercalate)
import Control.Concurrent (threadDelay)
import System.IO
-- I love how amazingly concise Haskell code can be. This same program in C,C++ or Java
-- would be at least twice as long.
pascal :: Int -> Int -> Int
pascal row col | col >= 0 && col <= row =
if row == 0 || col == 0 || row == col
then 1
else pascal (row - 1) (col - 1) + pascal (row - 1) col
pascal _ _ = 0
pascalsTriangle :: Int -> [[Int]]
pascalsTriangle rows =
[[pascal row col | col <- [0..row]] | row <- [0..rows]]
main :: IO ()
main = do
putStrLn ""
putStr "Starting at row #0,how many rows of Pascal's Triangle do you want to print out? "
hFlush stdout
numRows <- (\s -> read s :: Int) <$> getLine
let triangle = pascalsTriangle numRows
triangleOfStrings = map (intercalate ",") $ map (map show) triangle
lengthOfLastDiv2 = div ((length . last) triangleOfStrings) 2
putStrLn ""
mapM_ (\s -> let spaces = [' ' | x <- [1 .. lengthOfLastDiv2 - div (length s) 2]]
in (putStrLn $ spaces ++ s) >> threadDelay 200000) triangleOfStrings
putStrLn ""
我上面的小程序找到了Pascal Triangle的值。但是,如果编译并使用它,您会发现“三角形”看起来更像是圣诞树,而不是三角形!哎呀!
我只是占用最后一行的一半的长度,然后减去前一行的一半,然后创建那么多空格以添加到每个字符串的开头。它几乎可以工作,但是我正在寻找等边三角形的效果,但对我来说,它就像是倾斜的圣诞树!有一个更好的方法吗。除了一些编程人才,我还缺少什么?谢谢您的帮助。这不是家庭作业。我只是为了娱乐和娱乐而这样做。感谢您的帮助。
最佳。 道格拉斯·莱威特。
解决方法
这是一个简单的实现:
space n = replicate n ' '
pad n s | n < length s = take n s
pad n s = space (n - length s) ++ s
triangle = iterate (\ xs -> zipWith (+) (xs ++ [0]) (0:xs)) [1]
rowPrint n hw xs = space (n * hw) ++ concatMap (pad (2*hw) . show) xs
triRows n hw = [rowPrint (n-i) hw row | (i,row) <- zip [1..n] triangle]
main = do
s <- getLine
mapM_ putStrLn (triRows (read s) 2)
请注意,triangle
是由递归关系生成的无限Pascal三角形。同样,hw
代表“半角宽度”:分配用于打印数字的宽度的一半,而pad
是严格的左键,可以截断输出而不破坏格式。