Roman numerals/Decode: Difference between revisions

Content added Content deleted
(→‎Haskell :: mapAccum: Preferred Data.Bifunctor to Control.Arrow, applied Ormolu)
m (→‎mapAccumR: Qualified import of Data.Map.Strict, tidied)
Line 3,088: Line 3,088:
Or, in a '''mapAccumR''' version:
Or, in a '''mapAccumR''' version:
<lang Haskell>import Data.List (mapAccumR)
<lang Haskell>import Data.List (mapAccumR)
import Data.Map.Strict as M
import qualified Data.Map.Strict as M
import Data.Maybe (maybe)
import Data.Maybe (maybe)

fromRoman :: String -> Maybe Int
fromRoman :: String -> Maybe Int
fromRoman cs =
fromRoman cs =
let go l r
let go l r
| l > r = (-r, l)
| l > r = (- r, l)
| otherwise = (r, l)
| otherwise = (r, l)
in traverse (`M.lookup` mapRoman) cs >>=
in traverse (`M.lookup` mapRoman) cs
(Just . sum . ((:) <$> fst <*> snd) . mapAccumR go 0)
>>= ( Just . sum . ((:) <$> fst <*> snd)
. 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 -------------------------
main :: IO ()
main :: IO ()
main =
main =
putStrLn $
putStrLn $
fTable
fTable
"Decoding Roman numbers:\n"
"Decoding Roman numbers:\n"
show
show
(maybe "Unrecognised character" show)
(maybe "Unrecognised character" show)
fromRoman
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 ----------------------
fTable ::
String ->
(a -> String) ->
(b -> String) ->
(a -> b) ->
[a] ->
String
fTable s xShow fxShow f xs =
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>
( ((<>) . rjust w ' ' . xShow)
<*> ((" -> " <>) . fxShow . f)
)
xs
where
rjust n c = drop . length <*> (replicate n c <>)
w = maximum (length . xShow <$> xs)</lang>
{{Out}}
{{Out}}
<pre>Decoding Roman numbers:
<pre>Decoding Roman numbers: