Faulhaber's formula: Difference between revisions
Content added Content deleted
(→Haskell: Replaced Control.Arrow with bimap and an applicative. Tidied.) |
|||
Line 937: | Line 937: | ||
<lang Haskell>import Data.Ratio ((%), numerator, denominator) |
<lang Haskell>import Data.Ratio ((%), numerator, denominator) |
||
import Data.List (intercalate, transpose) |
import Data.List (intercalate, transpose) |
||
import |
import Data.Bifunctor (bimap) |
||
import Data.Char (isSpace) |
import Data.Char (isSpace) |
||
import Data.Monoid ((<>)) |
import Data.Monoid ((<>)) |
||
import Data.Bool (bool) |
import Data.Bool (bool) |
||
-- |
------------------------- FAULHABER ------------------------ |
||
faulhaber :: [[Rational]] |
faulhaber :: [[Rational]] |
||
faulhaber = |
faulhaber = |
||
Line 952: | Line 952: | ||
[] |
[] |
||
[0 ..] |
[0 ..] |
||
⚫ | |||
⚫ | |||
⚫ | |||
-- EXPRESSION STRINGS ------------------------------------- |
|||
⚫ | |||
⚫ | |||
⚫ | |||
-- Rows of (Power string, Ratio string) tuples -> Printable lines |
-- Rows of (Power string, Ratio string) tuples -> Printable lines |
||
Line 967: | Line 970: | ||
zipWith |
zipWith |
||
(\(lw, rw) col -> |
(\(lw, rw) col -> |
||
fmap (bimap (justifyLeft lw ' ') (justifyLeft rw ' ')) col) |
|||
(colWidths cols) |
(colWidths cols) |
||
cols) |
cols) |
||
⚫ | |||
⚫ | |||
-- Value pair -> String pair (lifted into list for use with >>=) |
-- Value pair -> String pair (lifted into list for use with >>=) |
||
ratioPower :: (Rational, Integer) -> [(String, String)] |
ratioPower :: (Rational, Integer) -> [(String, String)] |
||
ratioPower (nd, j) = |
ratioPower (nd, j) = |
||
let (num, den) = (numerator |
let (num, den) = ((,) . numerator <*> denominator) nd |
||
sn |
sn |
||
| num == 0 = [] |
| num == 0 = [] |
||
Line 986: | Line 992: | ||
s = sr <> sn |
s = sr <> sn |
||
in bool [(sn, sr)] [] (null s) |
in bool [(sn, sr)] [] (null s) |
||
-- Rows of uneven length -> All rows padded to length of longest |
-- Rows of uneven length -> All rows padded to length of longest |
||
fullTable :: [[(String, String)]] -> [[(String, String)]] |
fullTable :: [[(String, String)]] -> [[(String, String)]] |
||
Line 992: | Line 998: | ||
let lng = maximum $ length <$> xs |
let lng = maximum $ length <$> xs |
||
in (<>) <*> (flip replicate ([], []) . (-) lng . length) <$> xs |
in (<>) <*> (flip replicate ([], []) . (-) lng . length) <$> xs |
||
justifyLeft :: Int -> Char -> String -> String |
justifyLeft :: Int -> Char -> String -> String |
||
justifyLeft n c s = take n (s <> replicate n c) |
justifyLeft n c s = take n (s <> replicate n c) |
||
-- (Row index, Expression pairs) -> String joined by conjunctions |
-- (Row index, Expression pairs) -> String joined by conjunctions |
||
expressionRow :: (Int, [(String, String)]) -> String |
expressionRow :: (Int, [(String, String)]) -> String |
||
Line 1,007: | Line 1,013: | ||
(polyTerm <$> row) |
(polyTerm <$> row) |
||
] |
] |
||
-- (Power string, Ratio String) -> Combined string with possible '*' |
-- (Power string, Ratio String) -> Combined string with possible '*' |
||
polyTerm :: (String, String) -> String |
polyTerm :: (String, String) -> String |
||
Line 1,014: | Line 1,020: | ||
| head r == '-' = concat ["- ", l, " * ", tail r] |
| head r == '-' = concat ["- ", l, " * ", tail r] |
||
| otherwise = intercalate " * " [l, r] |
| otherwise = intercalate " * " [l, r] |
||
blank :: String -> Bool |
blank :: String -> Bool |
||
blank = all isSpace |
blank = all isSpace |
||
-- Maximum widths of power and ratio elements in each column |
-- Maximum widths of power and ratio elements in each column |
||
colWidths :: [[(String, String)]] -> [(Int, Int)] |
colWidths :: [[(String, String)]] -> [(Int, Int)] |
||
Line 1,025: | Line 1,031: | ||
(\(ls, rs) (lMax, rMax) -> (max (length ls) lMax, max (length rs) rMax)) |
(\(ls, rs) (lMax, rMax) -> (max (length ls) lMax, max (length rs) rMax)) |
||
(0, 0)) |
(0, 0)) |
||
-- Length of string excluding any leading '-' |
-- Length of string excluding any leading '-' |
||
unsignedLength :: String -> Int |
unsignedLength :: String -> Int |
||
unsignedLength xs = |
unsignedLength xs = |
||
let l = length xs |
let l = length xs |
||
in bool (bool l (l - 1) ('-' == head xs)) 0 (0 == l) |
in bool (bool l (l - 1) ('-' == head xs)) 0 (0 == l)</lang> |
||
⚫ | |||
⚫ | |||
⚫ | |||
{{Out}} |
{{Out}} |
||
<pre>0 -> n |
<pre>0 -> n |