From d3b6f6020f83921755fcf3df8a07c651c7c5ebf4 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Fri, 22 Apr 2016 15:19:22 +0200 Subject: [PATCH] add `CCList.{sorted_insert,is_sorted}` --- src/core/CCList.ml | 41 +++++++++++++++++++++++++++++++++++++++++ src/core/CCList.mli | 18 ++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/src/core/CCList.ml b/src/core/CCList.ml index 1416e5d0..857512ce 100644 --- a/src/core/CCList.ml +++ b/src/core/CCList.ml @@ -366,6 +366,47 @@ let sort_uniq (type elt) ?(cmp=Pervasives.compare) l = sort_uniq [10;10;10;10;1;10] = [1;10] *) +let is_sorted ?(cmp=Pervasives.compare) l = + let rec aux cmp = function + | [] | [_] -> true + | x :: ((y :: _) as tail) -> cmp x y <= 0 && aux cmp tail + in + aux cmp l + +(*$Q + Q.(list small_int) (fun l -> \ + is_sorted (List.sort Pervasives.compare l)) +*) + +let sorted_insert ?(cmp=Pervasives.compare) ?(uniq=false) x l = + let rec aux cmp uniq x left l = match l with + | [] -> List.rev_append left [x] + | y :: tail -> + match cmp x y with + | 0 -> + let l' = if uniq then l else x :: l in + List.rev_append left l' + | n when n<0 -> List.rev_append left (x :: l) + | _ -> aux cmp uniq x (y::left) tail + in + aux cmp uniq x [] l + +(*$Q + Q.(pair small_int (list small_int)) (fun (x,l) -> \ + let l = List.sort Pervasives.compare l in \ + is_sorted (sorted_insert ~uniq:true x l)) + Q.(pair small_int (list small_int)) (fun (x,l) -> \ + let l = List.sort Pervasives.compare l in \ + is_sorted (sorted_insert ~uniq:false x l)) + Q.(pair small_int (list small_int)) (fun (x,l) -> \ + let l = List.sort Pervasives.compare l in \ + let l' = sorted_insert ~uniq:false x l in \ + List.length l' = List.length l + 1) + Q.(pair small_int (list small_int)) (fun (x,l) -> \ + let l = List.sort Pervasives.compare l in \ + List.mem x (sorted_insert x l)) +*) + let uniq_succ ?(eq=(=)) l = let rec f acc l = match l with | [] -> List.rev acc diff --git a/src/core/CCList.mli b/src/core/CCList.mli index a3cacac1..68d593d0 100644 --- a/src/core/CCList.mli +++ b/src/core/CCList.mli @@ -184,6 +184,24 @@ val sorted_merge_uniq : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list removes duplicates @since 0.10 *) +val is_sorted : ?cmp:('a -> 'a -> int) -> 'a list -> bool +(** [is_sorted l] returns [true] iff [l] is sorted (according to given order) + @param cmp the comparison function (default [Pervasives.compare]) + @since NEXT_RELEASE *) + +val sorted_insert : ?cmp:('a -> 'a -> int) -> ?uniq:bool -> 'a -> 'a list -> 'a list +(** [sorted_insert x l] inserts [x] into [l] such that, if [l] was sorted, + then [sorted_insert x l] is sorted too. + @param uniq if true and [x] is already in sorted position in [l], then + [x] is not duplicated. Default [false] ([x] will be inserted in any case). + @since NEXT_RELEASE *) + +(*$Q + Q.(pair small_int (list small_int)) (fun (x,l) -> \ + let l = List.sort Pervasives.compare l in \ + is_sorted (sorted_insert x l)) +*) + val uniq_succ : ?eq:('a -> 'a -> bool) -> 'a list -> 'a list (** [uniq_succ l] removes duplicate elements that occur one next to the other. Examples: