From: "Nathan Mishra Linger" <nathan.mishralinger@gmail.com>
To: "Ashish Agarwal" <agarwal1975@gmail.com>
Cc: caml-list <caml-list@yquem.inria.fr>
Subject: Re: [Caml-list] is there a Roman Numeral library
Date: Sat, 15 Mar 2008 23:20:51 -0700 [thread overview]
Message-ID: <ab0c618e0803152320v253bd91ex5ca70d8c5b78bcc@mail.gmail.com> (raw)
In-Reply-To: <d8be5ae20803140950s6a0e3d98l39600975b8a6d418@mail.gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 611 bytes --]
Hi Ashish,
Here is something I wrote a while back. Let me know if it works out for
you.
Nathan
2008/3/14 Ashish Agarwal <agarwal1975@gmail.com>:
> Hi all. Does anyone have an OCaml libary for working with Roman Numerals?
> Probably easy to write but am hoping it already exists. Thank you.
>
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>
[-- Attachment #1.2: Type: text/html, Size: 1164 bytes --]
[-- Attachment #2: roman.ml --]
[-- Type: text/plain, Size: 2426 bytes --]
(*
roman numeral conversions
*)
(******************************************************************************)
(* arabic <== roman *)
exception BadNumeral of char
let eval = function
| 'I' -> 1
| 'V' -> 5
| 'X' -> 10
| 'L' -> 50
| 'C' -> 100
| 'D' -> 500
| 'M' -> 1000
| c -> raise(BadNumeral(c))
let arabic x =
let n = String.length x in
let rec loop i v p =
if i < n then
let c = eval (String.get x i) in
loop (i+1) (if p < c then v-p else v+p) c
else v + p
in
if n > 0
then let v = eval (String.get x 0) in loop 1 0 v
else 0
(******************************************************************************)
(* (arabic ==> roman) abstract interpretation on SIZES *)
let numerals_size = 7
let digit_size = function
| 0 -> 0 | 1 -> 1 | 2 -> 2 | 3 -> 3 | 4 -> 2
| 5 -> 1 | 6 -> 2 | 7 -> 3 | 8 -> 4 | 9 -> 2
| _ -> assert false
let rec count_size k = function
| (0,_) -> k
| (n,j) ->
if j >= 3
then count_size (digit_size (n mod 10) + k) (n/10,j-2)
else n+k
let roman_size n =
if n < 0 then 0 else
count_size 0 (n,numerals_size)
(******************************************************************************)
(* arabic ==> roman *)
exception Negative
let numerals = ['I';'V';'X';'L';'C';'D';'M']
let roman n =
let size = roman_size n in
let x = String.make size 'M' in
let ( ++ ) c k = String.set x k c; k-1 in
let digit d one five ten k =
match d with
| 0 -> k
| 1 -> one ++ k
| 2 -> one ++ (one ++ k)
| 3 -> one ++ (one ++ (one ++ k))
| 4 -> one ++ (five ++ k)
| 5 -> five ++ k
| 6 -> five ++ (one ++ k)
| 7 -> five ++ (one ++ (one ++ k))
| 8 -> five ++ (one ++ (one ++ (one ++ k)))
| 9 -> one ++ (ten ++ k)
| _ -> raise Negative
in
let rec count k = function
| 0,_ -> ()
| n,[_] -> ()
| n,(one :: five :: ((ten :: _) as next)) ->
count (digit (n mod 10) one five ten k) (n/10, next)
| _ -> assert false
in
count (size-1) (n,numerals); x
(******************************************************************************)
(* debugging *)
let debug = false
let () = if debug then begin
let rec upto i j = if i > j then [] else i :: upto (i+1) j in
let test n = arabic (roman n) = n in
let _ = List.for_all test (upto 0 5000) in
()
end
[-- Attachment #3: roman.mli --]
[-- Type: application/octet-stream, Size: 106 bytes --]
exception BadNumeral of char
val arabic : string -> int
exception Negative
val roman : int -> string
next prev parent reply other threads:[~2008-03-16 6:21 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-14 16:50 Ashish Agarwal
2008-03-14 20:29 ` [Caml-list] " Dave Benjamin
2008-03-16 6:20 ` Nathan Mishra Linger [this message]
2008-03-16 23:25 ` Ashish Agarwal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ab0c618e0803152320v253bd91ex5ca70d8c5b78bcc@mail.gmail.com \
--to=nathan.mishralinger@gmail.com \
--cc=agarwal1975@gmail.com \
--cc=caml-list@yquem.inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox