Roman numerals/Decode: Difference between revisions

m
→‎mapAccumR: Qualified import of Data.Map.Strict, tidied
(→‎Haskell :: mapAccum: Preferred Data.Bifunctor to Control.Arrow, applied Ormolu)
m (→‎mapAccumR: Qualified import of Data.Map.Strict, tidied)
Line 3,088:
Or, in a '''mapAccumR''' version:
<lang Haskell>import Data.List (mapAccumR)
import qualified Data.Map.Strict as M
import Data.Maybe (maybe)
 
fromRoman :: String -> Maybe Int
fromRoman cs =
let go l r
| l > r = (- r, l)
| otherwise = (r, l)
in traverse (`M.lookup` mapRoman) cs >>=
>>= ( Just . sum . ((:) <$> fst <*> snd) . mapAccumR go 0)
. mapAccumR go 0
)
mapRoman :: Map Char Int
 
mapRoman = M.fromList $ zip "MDCLXVI " [1000, 500, 100, 50, 10, 5, 1, 0]
mapRoman :: M.Map Char Int
mapRoman =
-- TEST ---------------------------------------------------
M.fromList $
zip
"MDCLXVI "
[ 1000,
500,
100,
50,
10,
5,
1,
0
]
 
-- TEST -------------------------- TEST -------------------------
main :: IO ()
main =
putStrLn $
fTable
"Decoding Roman numbers:\n"
show
(maybe "Unrecognised character" show)
fromRoman
[ "MDCLXVI",
["MDCLXVI", "MCMXC", "MMVIII", "MMXVI", "MMXVIII", "MMXBIII"]
"MCMXC",
"MMVIII",
-- FORMATTING ---------------------------------------------
"MMXVI",
fTable :: String -> (a -> String) -> (b -> String) -> (a -> b) -> [a] -> String
"MMXVIII",
"MMXBIII"
]
 
-- FORMATTING ----------------------- FORMATTING ----------------------
fTable ::
String ->
(a -> String) ->
(b -> String) ->
(a -> b) ->
[a] ->
String
fTable s xShow fxShow f xs =
unlines $
let w = maximum (length . xShow <$> xs)
s :
rjust n c = drop <$> length <*> (replicate n c ++)
in unlines $fmap
s : fmap( (((++<>) . rjust w ' ' . xShow) <*> ((" -> " ++) . fxShow . f)) xs</lang>
<*> ((" -> " <>) . fxShow . f)
)
xs
where
rjust n c = drop <$>. length <*> (replicate n c ++<>)
let w = maximum (length . xShow <$> xs)</lang>
{{Out}}
<pre>Decoding Roman numbers:
9,659

edits