77 lines
1.9 KiB
Haskell
77 lines
1.9 KiB
Haskell
-- | Find number to base b
|
|
bin
|
|
:: Int -- ^ number n
|
|
-> [Int] -- ^ digits of n in binary as list. LSB first.
|
|
bin n
|
|
| n==0 = [0]
|
|
| otherwise = helper n
|
|
where
|
|
helper n
|
|
| n==0 = []
|
|
| otherwise = rem:helper nxt
|
|
where
|
|
rem = mod n 2
|
|
nxt = quot n 2
|
|
|
|
-- | Find value for aCb where a and b ∈ {0, 1}
|
|
nCkBin
|
|
:: (Int, Int) -- ^ a and b values as tuple
|
|
-> Int -- ^ aCb value
|
|
nCkBin (0, 1) = 0
|
|
nCkBin _ = 1
|
|
|
|
-- | Calculate nCr value
|
|
nCr
|
|
:: Int -- ^ n
|
|
-> Int -- ^ r
|
|
-> Int -- ^ nCr
|
|
nCr a b = product $ map nCkBin $ zip apad bpad
|
|
where
|
|
abin = bin a
|
|
bbin = bin b
|
|
alen = length abin
|
|
blen = length bbin
|
|
maxlen = max alen blen
|
|
apad = abin ++ replicate (maxlen-alen) 0
|
|
bpad = bbin ++ replicate (maxlen-blen) 0
|
|
|
|
-- | Find values for one level
|
|
oneLine
|
|
:: Int -- ^ current level
|
|
-> [Int] -- ^ values of the level
|
|
oneLine lvl = [nCr lvl r | r <- [0..lvl]]
|
|
|
|
-- | Find values of all levels
|
|
allLines
|
|
:: Int -- ^ maximum level
|
|
-> [[Int]] -- ^ values of levels. Values of each level is in a separate list
|
|
allLines maxLvl = [oneLine i | i <- [0..maxLvl]]
|
|
|
|
-- | Find values of a level and format it as a string
|
|
fmtOneLine
|
|
:: Int -- ^ maximum level
|
|
-> Int -- ^ current level
|
|
-> String -- ^ formatted string
|
|
fmtOneLine maxLvl lvl = begg ++ bodyhead ++ bodytail
|
|
where
|
|
begg = replicate (maxLvl-lvl) ' '
|
|
digitstr = map show $ oneLine lvl
|
|
bodyhead = head digitstr
|
|
bodytail = foldl (++) "" $ map ((++) " ") $ tail digitstr
|
|
|
|
|
|
-- | Find values of the entire Pascal triangle and format it as a string
|
|
fmtAllLines
|
|
:: Int -- ^ maximum level
|
|
-> String -- ^ formatted, read-to-print, string
|
|
fmtAllLines maxLvl = foldl (++) "" $ map ((++) "\n") strLines
|
|
where
|
|
strLines = [fmtOneLine maxLvl lvl | lvl <- [0..maxLvl]]
|
|
|
|
main = do
|
|
putStrLn "Enter max level:"
|
|
maxLevelStr <- getLine
|
|
let maxLevel = read maxLevelStr :: Int
|
|
let ll = allLines maxLevel
|
|
putStrLn $ fmtAllLines maxLevel
|