package biocaml
The OCaml Bioinformatics Library
Install
Dune Dependency
Authors
Maintainers
Sources
biocaml-0.11.2.tbz
sha256=fae219e66db06f81f3fd7d9e44717ccf2d6d85701adb12004ab4ae6d3359dd2d
sha512=f6abd60dac2e02777be81ce3b5acdc0db23b3fa06731f5b2d0b32e6ecc9305fe64f407bbd95a3a9488b14d0a7ac7c41c73a7e18c329a8f18febfc8fd50eccbc6
doc/src/biocaml.unix/roman_num.ml.html
Source file roman_num.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
module Roman = struct (* Roman module courtesy of Nathan Mishra Linger, as posted on Caml List. *) (****************************************************************************) (* 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:string) : int = 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:int) : string = let size = roman_size n in let x = Bytes.make size 'M' in let ( ++ ) c k = Bytes.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,(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); Bytes.to_string x end (******************************************************************************) (* Following is by Ashish Agarwal, which just wraps above functions to provide API following Biocaml's conventions. Only real deviation is that in above [roman 0] returns empty string instead of an error. Below, we explicitly disallow 0. *) open Roman type t = int let of_roman s = try Ok (arabic (String.uppercase s)) with BadNumeral c -> error "invalid char in Roman numeral" c sexp_of_char let of_arabic i = if i > 0 then Ok i else error "invalid non-positive Roman numeral" i sexp_of_int let to_roman = roman let to_arabic = Fn.id
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>