Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,27 @@
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");
;;

View file

@ -0,0 +1,57 @@
(* 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)