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