-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRomanNumerals.hs
36 lines (29 loc) · 928 Bytes
/
RomanNumerals.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
module RomanNumerals (intToRoman,romanToInt) where
import Prelude hiding (floor)
import Control.Monad
type RomanNumber=String
arabics=[1,4,5,9,10,40,50,90,100,400,500,900,1000]
romans=["I","IV","V","IX","X","XL","L","XC","C","CD","D","CM","M"]
arabicsRomans :: [(Int,RomanNumber)]
arabicsRomans=zip arabics romans
romansArabics :: [(RomanNumber,Int)]
romansArabics=zip romans arabics
intToRoman :: Int -> RomanNumber
intToRoman 0=""
intToRoman num=
case lookup num arabicsRomans of
Just roman-> roman
Nothing-> intToRoman x ++ intToRoman y
where x= floor num arabics
y= num - x
floor :: (Ord a) => a -> [a] -> a
floor x=maximum.filter(<= x)
(<+>)=liftM2 (+)
romanToInt :: RomanNumber -> Maybe Int
romanToInt []= Nothing
romanToInt [x] = lookup [x] romansArabics
romanToInt (x:y:xs) =
case lookup [x,y] romansArabics of
Nothing-> rtoi [x] <+> rtoi (y:xs)
num-> num <+> rtoi xs
where rtoi=romanToInt