As a mostly-newbie Haskell / fp programmer (one who only read http://learnyouahaskell.com/) I wanted to exercise my functional coding skills, by resolving non-helloworld programming challenges. So I’ve tried something classical:
Write a program that will convert an integer in the range of [1 .. 3,888,000] to the equivalent roman numeral:
The symbols are: (I = 1); (V = 5); (X = 10); (L = 50); (C = 100); (D = 500); (M = 1,000); (upperscore V = 5,000); (upperscore X = 10,000); (upperscore L = 50,000); (upperscore C = 100,000); (upperscore D = 500,000); (upperscore M = 1,000,000) .
- If a letter if followed by another with equal or lesser value, the two numbers are added (eg. XX = 20, LV = 55);
- If a letter is followed by another with greater value, the first is subtracted from the second (eg. IV = 4, XC = 90);
The numbers from [1..10]: I, II, III, IV, V, VI, VII, VIII, IX, X
Other numbers: CDLVI = 456 , MCDXLIV = 1444 , MMMI = 3001 , etc.
and now… The solution (one of them, probably far from the best)
The main idea was to divide my solution into small reusable blocks.
1. First I’ve written a function, figures, that transforms a given number into a (reverse) list of figures. For example, 1113 becomes [3,1,1,1], 1234 becomes [4,3,2,1] and so on…
figures :: Int -> [Int]
figures 0 = 
figures x = x `mod` 10 : figures (x `div` 10)
2. Then I defined a list (of Strings), romans, containing all the roman numerals. The upperscored versions were coded using an underscore :), like (upperscore X) = _X = 10, 000 .