Roman numerals/Decode: Difference between revisions

→‎Haskell :: mapAccum: Preferred Data.Bifunctor to Control.Arrow, applied Ormolu
(→‎Haskell :: mapAccum: Preferred Data.Bifunctor to Control.Arrow, applied Ormolu)
Line 3,046:
====mapAccum====
Or, expressing '''romanValue''' in terms of '''mapAccumL''' (avoiding recursive descent, and visiting each k v pair just once)
<lang Haskell>import Data.ListBifunctor (mapAccumL, isPrefixOfbimap)
import ControlData.ArrowList ((***)isPrefixOf, mapAccumL)
 
romanValue :: String -> Int
romanValue =
let tr s (k, v) =
until
until (not . isPrefixOf k . fst) (drop (length k) *** (v +)) (s, 0)
in sum .
(bimap ((drop . length) k) (v +))
snd .
flip (s, 0)
in sum .
(mapAccumL tr)
[ ("M",. 1000)snd
, ("CM",. 900)flip
, ("D",mapAccumL 500tr)
, [ ("CDM", 4001000),
, ("CCM", 100900),
, ("XCD", 90500),
, ("LCD", 50400),
, ("XLC", 40100),
, ("XXC", 1090),
, ("IXL", 950),
, ("VXL", 540),
, ("IVX", 410),
, ("IIX", 19),
] ("V", 5),
("IV", 4),
("I", 1)
snd . ]
 
main :: IO ()
main =
mapM_
mapM_ (print . romanValue) ["MDCLXVI", "MCMXC", "MMVIII", "MMXVI", "MMXVII"]</lang>
(print . romanValue)
[ "MDCLXVI",
"MCMXC",
"MMVIII",
"MMXVI",
"MMXVII"
]</lang>
 
Or, in a '''mapAccumR''' version:
9,655

edits