CCArray(feat): Add max,argmax,min,argmin and their _exn conterpart

This commit is contained in:
Fardale 2023-04-12 11:52:57 +02:00
parent 4a46fa4d71
commit ff3e838553
4 changed files with 153 additions and 1 deletions

View file

@ -153,6 +153,60 @@ let find_idx p a =
None)
a 0
let max cmp a =
if Array.length a = 0 then None
else Some (
fold
(fun acc elt -> if cmp acc elt < 0 then elt else acc)
a.(0)
a)
let max_exn cmp a =
match max cmp a with
| None -> invalid_arg __FUNCTION__
| Some elt -> elt
let argmax cmp a =
if Array.length a = 0 then None
else Some (
foldi
(fun acc i elt -> if cmp a.(acc) elt < 0 then i else acc)
0
a)
let argmax_exn cmp a =
match argmax cmp a with
| None -> invalid_arg __FUNCTION__
| Some elt -> elt
let min cmp a =
if Array.length a = 0 then None
else Some (
fold
(fun acc elt -> if cmp acc elt > 0 then elt else acc)
a.(0)
a)
let min_exn cmp a =
match min cmp a with
| None -> invalid_arg __FUNCTION__
| Some elt -> elt
let argmin cmp a =
if Array.length a = 0 then None
else Some (
foldi
(fun acc i elt -> if cmp a.(acc) elt > 0 then i else acc)
0
a)
let argmin_exn cmp a =
match argmin cmp a with
| None -> invalid_arg __FUNCTION__
| Some elt -> elt
let filter_map f a =
let rec aux acc i =
if i = Array.length a then (
@ -275,7 +329,7 @@ let rec _exists2 p a1 a2 i1 i2 ~len =
&& (p a1.(i1) a2.(i2) || _exists2 p a1 a2 (i1 + 1) (i2 + 1) ~len:(len - 1))
let exists2 p a b =
_exists2 p a b 0 0 ~len:(min (Array.length a) (Array.length b))
_exists2 p a b 0 0 ~len:(Stdlib.min (Array.length a) (Array.length b))
let _fold2 f acc a b i j ~len =
let rec aux acc o =

View file

@ -142,6 +142,47 @@ val find_idx : ('a -> bool) -> 'a t -> (int * 'a) option
and [f x] holds. Otherwise returns [None].
@since 0.3.4 *)
val max : ('a -> 'a -> int) -> 'a t -> 'a option
(** [max cmp a] returns [None] if [a] is empty, otherwise, returns [Some e] where [e]
is a maximum element in [a] with respect to [cmp].
@since NEXT_RELEASE *)
val max_exn : ('a -> 'a -> int) -> 'a t -> 'a
(** [max_exn cmp a] is like {!max}, but
@raise Invalid_argument if [a] is empty.
@since NEXT_RELEASE *)
val argmax : ('a -> 'a -> int) -> 'a t -> int option
(** [argmax cmp a] returns [None] if [a] is empty, otherwise, returns [Some i] where [i]
is the index of a maximum element in [a] with respect to [cmp].
@since NEXT_RELEASE *)
val argmax_exn : ('a -> 'a -> int) -> 'a t -> int
(** [argmax_exn cmp a] is like {!argmax}, but
@raise Invalid_argument if [a] is empty.
@since NEXT_RELEASE *)
val min : ('a -> 'a -> int) -> 'a t -> 'a option
(** [min cmp a] returns [None] if [a] is empty, otherwise, returns [Some e] where [e]
is a minimum element in [a] with respect to [cmp].
@since NEXT_RELEASE *)
val min_exn : ('a -> 'a -> int) -> 'a t -> 'a
(** [min_exn cmp a] is like {!min}, but
@raise Invalid_argument if [a] is empty.
@since NEXT_RELEASE *)
val argmin : ('a -> 'a -> int) -> 'a t -> int option
(** [argmin cmp a] returns [None] if [a] is empty, otherwise, returns [Some i] where [i]
is the index of a minimum element in [a] with respect to [cmp].
@since NEXT_RELEASE *)
val argmin_exn : ('a -> 'a -> int) -> 'a t -> int
(** [argmin_exn cmp a] is like {!argmin}, but
@raise Invalid_argument if [a] is empty.
@since NEXT_RELEASE *)
val lookup : cmp:'a ord -> 'a -> 'a t -> int option
(** [lookup ~cmp key a] lookups the index of some key [key] in a sorted array [a].
Undefined behavior if the array [a] is not sorted wrt [~cmp].

View file

@ -141,6 +141,47 @@ val find_idx : f:('a -> bool) -> 'a t -> (int * 'a) option
and [f x] holds. Otherwise returns [None].
@since 0.3.4 *)
val max : cmp:('a -> 'a -> int) -> 'a t -> 'a option
(** [max ~cmp a] returns [None] if [a] is empty, otherwise, returns [Some e] where [e]
is a maximum element in [a] with respect to [cmp].
@since NEXT_RELEASE *)
val max_exn : cmp:('a -> 'a -> int) -> 'a t -> 'a
(** [max_exn ~cmp a] is like {!max}, but
@raise Invalid_argument if [a] is empty.
@since NEXT_RELEASE *)
val argmax : cmp:('a -> 'a -> int) -> 'a t -> int option
(** [argmax ~cmp a] returns [None] if [a] is empty, otherwise, returns [Some i] where [i]
is the index of a maximum element in [a] with respect to [cmp].
@since NEXT_RELEASE *)
val argmax_exn : cmp:('a -> 'a -> int) -> 'a t -> int
(** [argmax_exn ~cmp a] is like {!argmax}, but
@raise Invalid_argument if [a] is empty.
@since NEXT_RELEASE *)
val min : cmp:('a -> 'a -> int) -> 'a t -> 'a option
(** [min ~cmp a] returns [None] if [a] is empty, otherwise, returns [Some e] where [e]
is a minimum element in [a] with respect to [cmp].
@since NEXT_RELEASE *)
val min_exn : cmp:('a -> 'a -> int) -> 'a t -> 'a
(** [min_exn ~cmp a] is like {!min}, but
@raise Invalid_argument if [a] is empty.
@since NEXT_RELEASE *)
val argmin : cmp:('a -> 'a -> int) -> 'a t -> int option
(** [argmin ~cmp a] returns [None] if [a] is empty, otherwise, returns [Some i] where [i]
is the index of a minimum element in [a] with respect to [cmp].
@since NEXT_RELEASE *)
val argmin_exn : cmp:('a -> 'a -> int) -> 'a t -> int
(** [argmin_exn ~cmp a] is like {!argmin}, but
@raise Invalid_argument if [a] is empty.
@since NEXT_RELEASE *)
val lookup : cmp:('a ord[@keep_label]) -> key:'a -> 'a t -> int option
(** [lookup ~cmp ~key a] lookups the index of some key [key] in a sorted array [a].
Undefined behavior if the array [a] is not sorted wrt [cmp].

View file

@ -140,6 +140,22 @@ t @@ fun () -> rev [| 1; 2 |] = [| 2; 1 |];;
t @@ fun () -> rev [||] = [||];;
q Q.(array small_int) (fun a -> mem 1 a = Array.mem 1 a);;
eq (Some 3) (max Stdlib.compare [| 1; 2; 3 |]);;
eq (Some 4) (max Stdlib.compare [| 4; -1; 2; 3 |]);;
eq (None) (max Stdlib.compare [||]);;
eq (Some 2) (argmax Stdlib.compare [| 1; 2; 3 |]);;
eq (Some 0) (argmax Stdlib.compare [| 4; -1; 2; 3 |]);;
eq (None) (argmax Stdlib.compare [||]);;
eq (Some 1) (min Stdlib.compare [| 1; 2; 3 |]);;
eq (Some ~-1) (min Stdlib.compare [| 4; -1; 2; 3 |]);;
eq (None) (min Stdlib.compare [||]);;
eq (Some 0) (argmin Stdlib.compare [| 1; 2; 3 |]);;
eq (Some 1) (argmin Stdlib.compare [| 4; -1; 2; 3 |]);;
eq (None) (argmin Stdlib.compare [||]);;
t @@ fun () ->
filter_map
(fun x ->