How to resolve the algorithm Roman numerals/Decode step by step in the OCaml programming language
Published on 12 May 2024 09:40 PM
How to resolve the algorithm Roman numerals/Decode step by step in the OCaml programming language
Table of Contents
Problem Statement
Create a function that takes a Roman numeral as its argument and returns its value as a numeric decimal integer. You don't need to validate the form of the Roman numeral. Modern Roman numerals are written by expressing each decimal digit of the number to be encoded separately, starting with the leftmost decimal digit and skipping any 0s (zeroes). 1990 is rendered as MCMXC (1000 = M, 900 = CM, 90 = XC) and 2008 is rendered as MMVIII (2000 = MM, 8 = VIII). The Roman numeral for 1666, MDCLXVI, uses each letter in descending order.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Roman numerals/Decode step by step in the OCaml programming language
Source code in the ocaml programming language
let decimal_of_roman roman =
let arabic = ref 0 in
let lastval = ref 0 in
for i = (String.length roman) - 1 downto 0 do
let n =
match roman.[i] with
| 'M' | 'm' -> 1000
| 'D' | 'd' -> 500
| 'C' | 'c' -> 100
| 'L' | 'l' -> 50
| 'X' | 'x' -> 10
| 'V' | 'v' -> 5
| 'I' | 'i' -> 1
| _ -> 0
in
if n < !lastval
then arabic := !arabic - n
else arabic := !arabic + n;
lastval := n
done;
!arabic
let () =
Printf.printf " %d\n" (decimal_of_roman "MCMXC");
Printf.printf " %d\n" (decimal_of_roman "MMVIII");
Printf.printf " %d\n" (decimal_of_roman "MDCLXVI");
;;
(* Scan the roman number from right to left. *)
(* When processing a roman digit, if the previously processed roman digit was
* greater than the current one, we must substract the latter from the current
* total, otherwise add it.
* Example:
* - MCMLXX read from right to left is XXLMCM
* the sum is 10 + 10 + 50 + 1000 - 100 + 1000 *)
let decimal_of_roman roman =
(* Use 'String.uppercase' for OCaml 4.02 and previous. *)
let rom = String.uppercase_ascii roman in
(* A simple association list. IMHO a Hashtbl is a bit overkill here. *)
let romans = List.combine ['I'; 'V'; 'X'; 'L'; 'C'; 'D'; 'M']
[1; 5; 10; 50; 100; 500; 1000] in
let compare x y =
if x < y then -1 else 1
in
(* Scan the string from right to left using index i, and keeping track of
* the previously processed roman digit in prevdig. *)
let rec doloop i prevdig =
if i < 0 then 0
else
try
let currdig = List.assoc rom.[i] romans in
(currdig * compare currdig prevdig) + doloop (i - 1) currdig
with
(* Ignore any incorrect roman digit and just process the next one. *)
Not_found -> doloop (i - 1) 0
in
doloop (String.length rom - 1) 0
(* Some simple tests. *)
let () =
let testit roman decimal =
let conv = decimal_of_roman roman in
let status = if conv = decimal then "PASS" else "FAIL" in
Printf.sprintf "[%s] %s\tgives %d.\tExpected: %d.\t"
status roman conv decimal
in
print_endline ">>> Usual roman numbers.";
print_endline (testit "MCMXC" 1990);
print_endline (testit "MMVIII" 2008);
print_endline (testit "MDCLXVI" 1666);
print_newline ();
print_endline ">>> Roman numbers with lower case letters are OK.";
print_endline (testit "McmXC" 1990);
print_endline (testit "MMviii" 2008);
print_endline (testit "mdCLXVI" 1666);
print_newline ();
print_endline ">>> Incorrect roman digits are ignored.";
print_endline (testit "McmFFXC" 1990);
print_endline (testit "MMviiiPPPPP" 2008);
print_endline (testit "mdCLXVI_WHAT_NOW" 1666);
print_endline (testit "2 * PI ^ 2" 1); (* The I in PI... *)
print_endline (testit "E = MC^2" 1100)
You may also check:How to resolve the algorithm Sorting algorithms/Merge sort step by step in the REBOL programming language
You may also check:How to resolve the algorithm Arithmetic/Integer step by step in the OCaml programming language
You may also check:How to resolve the algorithm Hello world/Text step by step in the Egel programming language
You may also check:How to resolve the algorithm 100 doors step by step in the Dafny programming language
You may also check:How to resolve the algorithm Catalan numbers step by step in the V (Vlang) programming language