Faulhaber's triangle: Difference between revisions

→‎{{header|Haskell}}: Tidied, replaced an Arrow with an Applicative.
(→‎{{header|Haskell}}: Tidied, replaced an Arrow with an Applicative.)
Line 945:
 
=={{header|Haskell}}==
{{works with|GHC|78.106.34}}
<lang haskell>import Data.Ratio (Ratio, numerator, denominator, (%))
import Control.Arrow ((&&&))
 
-- FAULHABER -------------------------------------------- FAULHABER -----------------------
 
-- Infinite list of rows of Faulhaber's triangle
faulhaberTriangle :: [[Rational]]
Line 965:
faulhaber p n = sum (zipWith ((*) . (n ^)) [1 ..] (faulhaberTriangle !! p))
 
-- DISPLAY ---------------------------------------------------------------------
-- (Max numerator+denominator widths) -> Column width -> Filler -> Ratio -> String
justifyRatio :: (Int, Int) -> Int -> Char -> Rational -> String
justifyRatio (wn, wd) n c nd =
let [num, den] = [numerator, denominator] <*> [nd]
w = max n (wn + wd + 2) -- Minimum column width, or more if specified.
in if 1 == den
then center w c (show num)
else let (q, r) = quotRem (w - 1) 2
in concat
[ justifyRight q c (show num)
, "/"
, justifyLeft (q + r) c (show den)
]
 
-- DISPLAY -------------------------------------------- TEST -------------------------
center, justifyLeft, justifyRight :: Int -> Char -> String -> String
center n c s =
let (q, r) = quotRem (n - length s) 2
in concat [replicate q c, s, replicate (q + r) c]
 
justifyLeft n c s = take n (s ++ replicate n c)
 
justifyRight n c s = drop (length s) (replicate n c ++ s)
 
-- List of Ratios -> (Max numerator width, Max denominator width)
maxWidths :: [[Rational]] -> (Int, Int)
maxWidths xss =
let widest f xs = maximum $ fmap (length . show . f) xs
in widest numerator &&& widest denominator $ concat xss
 
-- TEST ------------------------------------------------------------------------
main :: IO ()
main = do
Line 1,004 ⟶ 976:
[ unlines ((justifyRatio widths 8 ' ' =<<) <$> triangle)
, (show . numerator) (faulhaber 17 1000)
]</lang>
 
-- TEST ------------------------------------------------ DISPLAY ------------------------
 
-- (Max numerator+denominator widths) -> Column width -> Filler -> Ratio -> String
justifyRatio :: (Int, Int) -> Int -> Char -> Rational -> String
justifyRatio (wn, wd) n c nd = go $ [numerator, denominator] <*> [nd]
where
w = max n (wn + wd + 2) -- Minimum column width, or more if specified.
in if 1go ==[num, den]
| then1 == den = center w c (show num)
| otherwise =
else let (q, r) = quotRem (w - 1) 2
in concat
[ justifyRight q c (show num)
, "/"
, justifyLeft (q + r) c (show den)
]
 
center, justifyLeft, justifyRight, center :: Int -> Char -> String -> String
justifyLeft n c s = take n (s ++<> replicate n c)
 
justifyRight n c s = (drop (. length s) <*> (replicate n c ++ s<>)
 
center n c s =
let (q, r) = quotRem (n - length s) 2
pad = replicate q c
in concat [replicate q cpad, s, pad, replicate (q + r) c]
 
-- List of Ratios -> (Max numerator width, Max denominator width)
maxWidths :: [[Rational]] -> (Int, Int)
maxWidths xss =
let widest f xs = maximum $ fmap (length . show . f) xs
in ((,) . widest numerator &&&<*> widest denominator) $ concat xss</lang>
{{Out}}
<pre> 1
9,655

edits