Project Euler 89

http://projecteuler.net/index.php?section=problems&id=89


1000の位だけ特別扱い。

digits 0 = []
digits n = (digits (div n 10)) ++ [mod n 10]

num_length :: Int -> Int
num_length n = (div n 1000) + (sum (map f (digits (mod n 1000)))) where
        f n | n < 4  = n
            | n == 4 = 2
            | n < 9  = n - 4
            | n == 9 = 2

val 'I' = 1
val 'V' = 5
val 'X' = 10
val 'L' = 50
val 'C' = 100
val 'D' = 500
val 'M' = 1000

fromRoman [c] = val c
fromRoman (c1:c2:s) | less c1 c2 = (fromRoman (c2:s)) - (val c1)
                    | otherwise  = (fromRoman (c2:s)) + (val c1)
                            where less c1 c2 = (val c1) < (val c2)

save s = (length s) - (num_length (fromRoman s))

main = do
    cs <- readFile "roman.txt"
    print (sum (map save (lines cs)))