Last active
June 21, 2016 20:28
-
-
Save devstopfix/0d6529fe5d4085e92cc06aeb96798e1d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module RomanNumeral exposing (numeral_to_number) | |
type Digit = I | V | X | L | C | D | M | |
value : Digit -> number | |
value d = | |
case d of | |
I -> 1 | |
V -> 5 | |
X -> 10 | |
L -> 50 | |
C -> 100 | |
D -> 500 | |
M -> 1000 | |
-- todo parse String | |
parse : String -> List Digit | |
parse s = [M, X, M, I, V] | |
values : List Digit -> List number | |
values digits = List.map value digits | |
-- Chunk a list into a list of adjacent pairs | |
-- Tail is right padded with given value | |
chunk : comparable -> List comparable -> (List (comparable, comparable)) | |
chunk padding list = | |
case list of | |
[] -> | |
[] | |
[x] -> | |
[(x, padding)] | |
(x::y::xs) -> | |
(x,y)::(chunk padding (y::xs)) | |
-- chunk_numbers [1,2,3] == [[1,2], [2,3], [3,0]] | |
chunk_numbers = chunk 0 | |
-- Accumulate (sum) a list of pairs of numbers | |
accumulate : List (number, number) -> number | |
accumulate pairs = | |
List.foldr | |
(\ (a,b) acc -> if a >= b then acc + a else acc - a ) | |
0 pairs | |
numeral_to_number : String -> number | |
numeral_to_number s = | |
(parse s) | |
|> values | |
|> chunk_numbers | |
|> accumulate |
Solution using pattern matching:
module RomanNumeral exposing (numeral_to_number)
import String exposing (toList)
value : List Char -> number
value lc =
case lc of
('C' :: 'M' :: xs) ->
900 + value xs
('C' :: 'D' :: xs) ->
400 + value xs
('X' :: 'C' :: xs) ->
90 + value xs
('X' :: 'L' :: xs) ->
40 + value xs
('I' :: 'X' :: xs) ->
9 + (value xs)
('I' :: 'V' :: xs) ->
4 + value xs
('M' :: xs) ->
1000 + value xs
('D' :: xs) ->
500 + value xs
('C' :: xs) ->
100 + value xs
('L' :: xs) ->
50 + value xs
('X' :: xs) ->
10 + value xs
('V' :: xs) ->
5 + value xs
('I' :: xs) ->
1 + value xs
_ ->
0
numeral_to_number : String -> number
numeral_to_number s =
s
|> toList
|> value
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
TODO:
We need an error type: