From 6b377719c10d5ab3343fd5221f99a4a21008e25a Mon Sep 17 00:00:00 2001 From: Sébastien Dailly Date: Thu, 14 Mar 2024 08:26:58 +0100 Subject: Initial commit --- lib/csv/csv.ml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 lib/csv/csv.ml (limited to 'lib/csv/csv.ml') diff --git a/lib/csv/csv.ml b/lib/csv/csv.ml new file mode 100644 index 0000000..db7329d --- /dev/null +++ b/lib/csv/csv.ml @@ -0,0 +1,30 @@ +open StdLabels + +type t = int + +let column_of_char = function + | 'A' .. 'Z' as c -> Char.code c - (Char.code 'A' - 1) + | 'a' .. 'z' as c -> Char.code c - (Char.code 'a' - 1) + | c -> raise (Invalid_argument ("column: " ^ Char.escaped c)) + +let column_of_string : string -> int = + fun s -> + String.fold_left s ~init:0 ~f:(fun value c -> (value * 26) + column_of_char c) + +(** Accumulate the remaining for the successives divisions in a list. *) +let rec _to_char ~b i = + if i > 0 then + let res = i mod 26 in + let res = if res = 0 then 26 else res in + + let c = char_of_int @@ (res + 64) in + (* The modulo is accumulated in the list head, which is the expected + sequence *) + let b = c :: b in + + _to_char ~b @@ ((i - res) / 26) + else b + +let column_to_string i = + let res = _to_char ~b:[] i in + List.to_seq res |> String.of_seq -- cgit v1.2.3