Personal tools

Haskell Quiz/PP Pascal/Solution Ltriant

From HaskellWiki

< Haskell Quiz | PP Pascal(Difference between revisions)
Jump to: navigation, search
Current revision (10:52, 13 January 2007) (edit) (undo)
(sharpen cat)
 
(2 intermediate revisions not shown.)
Line 1: Line 1:
-
[[Category:Code]]
+
[[Category:Haskell Quiz solutions|PP Pascal]]
-
Works...kind of; adds a space or two (or three) to the end of each line.
+
Basically it builds the list of Pascal's triangle, then spaces the integers out (by adding trailing spaces to each integer), then indents each line by adding spaces onto the head of each list, strips off any trailing spaces then prints it all out.
<haskell>
<haskell>
Line 8: Line 8:
import System.Environment ( getArgs )
import System.Environment ( getArgs )
 +
fac :: Integer -> Integer
fac n = product [1..n]
fac n = product [1..n]
 +
 +
nck :: Integer -> Integer -> Integer
nck n k = (fac n) `div` ((fac $ n - k) * (fac k))
nck n k = (fac n) `div` ((fac $ n - k) * (fac k))
 +
 +
rstrip :: Eq a => a -> [a] -> [a]
 +
rstrip n t = reverse $ dropWhile (== n) $ reverse t
 +
 +
space_len :: Integer -> Integer
space_len n = mylength $ show $ (n-1) `nck` ((n-1) `div` 2)
space_len n = mylength $ show $ (n-1) `nck` ((n-1) `div` 2)
 +
 +
mylength :: [a] -> Integer
mylength = toInteger . length
mylength = toInteger . length
 +
indent :: Integer -> [String] -> [String]
indent n t =
indent n t =
-
(concat $ replicate (fromInteger $ (n-p) * space_len n) " "):t
+
(replicate (fromInteger $ (n-p) * space_len n) ' '):t
where p = mylength t
where p = mylength t
 +
space_out :: Integer -> [Integer] -> [String]
space_out n t =
space_out n t =
-
map (\x -> show x ++ (concat $ replicate (num_spaces x) " ")) t
+
map (\x -> show x ++ (replicate (num_spaces x) ' ')) t
where num_spaces x = fromInteger $ (2 * space_len n) - (mylength $ show x)
where num_spaces x = fromInteger $ (2 * space_len n) - (mylength $ show x)
 +
pp_pascal :: Integer -> [String]
pp_pascal n =
pp_pascal n =
-
map (concat . indent n . space_out n) $ f 0 n
+
map (rstrip ' ' . concat . indent n . space_out n) $ f 0 n
where f acc n | acc == n = []
where f acc n | acc == n = []
| otherwise = (map (nck acc) [0..acc]):(f (acc+1) n)
| otherwise = (map (nck acc) [0..acc]):(f (acc+1) n)
 +
main :: IO ()
main =
main =
do args <- getArgs
do args <- getArgs
case args of
case args of
-
[v] -> mapM_ putStrLn $ pp_pascal (read v :: Integer)
+
[v] -> mapM_ putStrLn $ pp_pascal $ read v
_ -> error "No argument specified."
_ -> error "No argument specified."
</haskell>
</haskell>

Current revision


Basically it builds the list of Pascal's triangle, then spaces the integers out (by adding trailing spaces to each integer), then indents each line by adding spaces onto the head of each list, strips off any trailing spaces then prints it all out.

module Main where
 
import System.Environment ( getArgs )
 
fac :: Integer -> Integer
fac n = product [1..n]
 
nck :: Integer -> Integer -> Integer
nck n k = (fac n) `div` ((fac $ n - k) * (fac k))
 
rstrip :: Eq a => a -> [a] -> [a]
rstrip n t = reverse $ dropWhile (== n) $ reverse t
 
space_len :: Integer -> Integer
space_len n = mylength $ show $ (n-1) `nck` ((n-1) `div` 2)
 
mylength :: [a] -> Integer
mylength = toInteger . length
 
indent :: Integer -> [String] -> [String]
indent n t =
    (replicate (fromInteger $ (n-p) * space_len n)  ' '):t
    where p = mylength t
 
space_out :: Integer -> [Integer] -> [String]
space_out n t =
    map (\x -> show x ++ (replicate (num_spaces x) ' ')) t
    where num_spaces x = fromInteger $ (2 * space_len n) - (mylength $ show x)
 
pp_pascal :: Integer -> [String]
pp_pascal n =
    map (rstrip ' ' . concat . indent n . space_out n) $ f 0 n
    where f acc n | acc == n  = []
                  | otherwise = (map (nck acc) [0..acc]):(f (acc+1) n)
 
main :: IO ()
main =
    do args <- getArgs
       case args of
         [v] -> mapM_ putStrLn $ pp_pascal $ read v
         _   -> error "No argument specified."