31 lines
785 B
Haskell
31 lines
785 B
Haskell
import qualified Data.Map.Strict as M
|
|
|
|
fromRoman :: String -> Int
|
|
fromRoman xs = partialSum + lastDigit
|
|
where
|
|
(partialSum, lastDigit) = foldl accumulate (0, 0) (evalRomanDigit <$> xs)
|
|
accumulate (partial, lastDigit) newDigit
|
|
| newDigit <= lastDigit = (partial + lastDigit, newDigit)
|
|
| otherwise = (partial - lastDigit, newDigit)
|
|
|
|
mapRoman :: M.Map Char Int
|
|
mapRoman =
|
|
M.fromList
|
|
[ ('I', 1)
|
|
, ('V', 5)
|
|
, ('X', 10)
|
|
, ('L', 50)
|
|
, ('C', 100)
|
|
, ('D', 500)
|
|
, ('M', 1000)
|
|
]
|
|
|
|
evalRomanDigit :: Char -> Int
|
|
evalRomanDigit c =
|
|
let mInt = M.lookup c mapRoman
|
|
in case mInt of
|
|
Just x -> x
|
|
_ -> error $ c : " is not a roman digit"
|
|
|
|
main :: IO ()
|
|
main = print $ fromRoman <$> ["MDCLXVI", "MCMXC", "MMVIII", "MMXVI", "MMXVII"]
|