2014-08-26 15:31:16 +02:00
|
|
|
open Core.Std;;
|
|
|
|
|
|
|
|
(* A range is a string of the type:
|
|
|
|
*
|
|
|
|
* "[36-53,72-107,126-131]"
|
|
|
|
*
|
|
|
|
* that should represent the list of integers
|
|
|
|
* [ 37 ; 37 ; 38 ; ... ; 52 ; 53 ; 72 ; 73 ; ... ; 106 ; 107 ; 126 ; 127 ; ...
|
|
|
|
* ; 130 ; 131 ]
|
2014-09-16 18:58:42 +02:00
|
|
|
*
|
|
|
|
* or it can be an integer
|
2014-08-26 15:31:16 +02:00
|
|
|
*)
|
|
|
|
|
|
|
|
|
2014-10-25 21:24:21 +02:00
|
|
|
type t = int list with sexp
|
2014-08-26 15:31:16 +02:00
|
|
|
|
|
|
|
let expand_range r =
|
|
|
|
match String.lsplit2 ~on:'-' r with
|
|
|
|
| Some (s, f) ->
|
|
|
|
begin
|
|
|
|
let start = Int.of_string s
|
|
|
|
and finish = Int.of_string f
|
|
|
|
in
|
|
|
|
assert (start <= finish) ;
|
|
|
|
let rec do_work = function
|
|
|
|
| i when i=finish -> [ i ]
|
|
|
|
| i -> i::(do_work (i+1))
|
|
|
|
in do_work start
|
|
|
|
end
|
|
|
|
| None ->
|
|
|
|
begin
|
|
|
|
match r with
|
|
|
|
| "" -> []
|
|
|
|
| _ -> [Int.of_string r]
|
|
|
|
end
|
|
|
|
;;
|
|
|
|
|
|
|
|
let of_string s =
|
2014-09-16 18:58:42 +02:00
|
|
|
match s.[0] with
|
|
|
|
| '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ->
|
|
|
|
[ int_of_string s ]
|
|
|
|
| _ ->
|
|
|
|
assert (s.[0] = '[') ;
|
|
|
|
assert (s.[(String.length s)-1] = ']') ;
|
|
|
|
let s = String.sub s 1 ((String.length s) - 2) in
|
|
|
|
let l = String.split ~on:',' s in
|
|
|
|
let l = List.map ~f:expand_range l in
|
2014-08-26 15:31:16 +02:00
|
|
|
List.concat l |> List.dedup ~compare:Int.compare |> List.sort ~cmp:Int.compare
|
|
|
|
;;
|
|
|
|
|
|
|
|
let to_string l =
|
|
|
|
let rec do_work buf symbol = function
|
|
|
|
| [] -> buf
|
|
|
|
| a::([] as t) ->
|
|
|
|
do_work (buf^symbol^(Int.to_string a)) "" t
|
|
|
|
| a::(b::q as t) ->
|
|
|
|
if (b-a = 1) then
|
|
|
|
do_work buf "-" t
|
|
|
|
else
|
|
|
|
do_work (buf^symbol^(Int.to_string a)^","^(Int.to_string b)) "" t
|
|
|
|
in
|
|
|
|
let result =
|
|
|
|
match l with
|
|
|
|
| [] ->
|
|
|
|
"[]"
|
|
|
|
| h::t ->
|
|
|
|
do_work ("["^(Int.to_string h)) "" l in
|
|
|
|
(String.sub result 0 ((String.length result)))^"]"
|
|
|
|
;;
|
|
|
|
|
|
|
|
let test_module () =
|
|
|
|
let s = "[72-107,36-53,126-131]" in
|
|
|
|
let l = of_string s in
|
|
|
|
print_string s ; print_newline () ;
|
|
|
|
List.iter ~f:(fun x -> Printf.printf "%d, " x) l ; print_newline () ;
|
|
|
|
to_string l |> print_string ; print_newline () ;
|
|
|
|
;;
|
|
|
|
|