mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-08 04:05:30 -05:00
add CCList.{cartesian_product,map_product_l}
This commit is contained in:
parent
4aa507c7bf
commit
ff53571a3b
2 changed files with 60 additions and 2 deletions
|
|
@ -277,8 +277,8 @@ let fold_product f acc l1 l2 =
|
||||||
(fun acc x1 ->
|
(fun acc x1 ->
|
||||||
List.fold_left
|
List.fold_left
|
||||||
(fun acc x2 -> f acc x1 x2)
|
(fun acc x2 -> f acc x1 x2)
|
||||||
acc l2
|
acc l2)
|
||||||
) acc l1
|
acc l1
|
||||||
|
|
||||||
let diagonal l =
|
let diagonal l =
|
||||||
let rec gen acc l = match l with
|
let rec gen acc l = match l with
|
||||||
|
|
@ -329,6 +329,44 @@ let pure = return
|
||||||
|
|
||||||
let (<*>) funs l = product (fun f x -> f x) funs l
|
let (<*>) funs l = product (fun f x -> f x) funs l
|
||||||
|
|
||||||
|
let cartesian_product l =
|
||||||
|
(* [left]: elements picked so far
|
||||||
|
[right]: sets to pick elements from
|
||||||
|
[acc]: accumulator for the result, to pass to continuation
|
||||||
|
[k]: continuation *)
|
||||||
|
let rec prod_rec left right k acc = match right with
|
||||||
|
| [] -> k acc (List.rev left)
|
||||||
|
| l1 :: tail ->
|
||||||
|
List.fold_left
|
||||||
|
(fun acc x -> prod_rec (x::left) tail k acc)
|
||||||
|
acc l1
|
||||||
|
in
|
||||||
|
prod_rec [] l (fun acc l' -> l' :: acc) []
|
||||||
|
|
||||||
|
(*$inject
|
||||||
|
let cmp_lii_unord l1 l2 : bool =
|
||||||
|
List.sort CCOrd.compare l1 = List.sort CCOrd.compare l2
|
||||||
|
*)
|
||||||
|
|
||||||
|
(*$= & ~printer:Q.Print.(list (list int)) ~cmp:cmp_lii_unord
|
||||||
|
[[1;3;4];[1;3;5];[1;3;6];[2;3;4];[2;3;5];[2;3;6]] \
|
||||||
|
(cartesian_product [[1;2];[3];[4;5;6]])
|
||||||
|
[] (cartesian_product [[1;2];[];[4;5;6]])
|
||||||
|
[[]] (cartesian_product [])
|
||||||
|
[[1;3;4;5;6];[2;3;4;5;6]] \
|
||||||
|
(cartesian_product [[1;2];[3];[4];[5];[6]])
|
||||||
|
*)
|
||||||
|
|
||||||
|
(* cartesian product of lists of lists *)
|
||||||
|
let map_product_l f l =
|
||||||
|
let l = List.map f l in
|
||||||
|
cartesian_product l
|
||||||
|
|
||||||
|
(*$Q
|
||||||
|
Q.(list_of_size Gen.(1--4) (list_of_size Gen.(0--4) small_int)) (fun l-> \
|
||||||
|
cmp_lii_unord (cartesian_product l) (map_product_l CCFun.id l))
|
||||||
|
*)
|
||||||
|
|
||||||
let sorted_merge ?(cmp=Pervasives.compare) l1 l2 =
|
let sorted_merge ?(cmp=Pervasives.compare) l1 l2 =
|
||||||
let rec recurse cmp acc l1 l2 = match l1,l2 with
|
let rec recurse cmp acc l1 l2 = match l1,l2 with
|
||||||
| [], _ -> List.rev_append acc l2
|
| [], _ -> List.rev_append acc l2
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,26 @@ val product : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
|
||||||
val fold_product : ('c -> 'a -> 'b -> 'c) -> 'c -> 'a t -> 'b t -> 'c
|
val fold_product : ('c -> 'a -> 'b -> 'c) -> 'c -> 'a t -> 'b t -> 'c
|
||||||
(** Fold on the cartesian product *)
|
(** Fold on the cartesian product *)
|
||||||
|
|
||||||
|
val cartesian_product : 'a t t -> 'a t t
|
||||||
|
(**
|
||||||
|
For example:
|
||||||
|
{[
|
||||||
|
# cartesian_product [[1;2];[3];[4;5;6]] =
|
||||||
|
[[1;3;4];[1;3;5];[1;3;6];[2;3;4];[2;3;5];[2;3;6]];;
|
||||||
|
# cartesian_product [[1;2];[];[4;5;6]] = [];;
|
||||||
|
# cartesian_product [[1;2];[3];[4];[5];[6]] =
|
||||||
|
[[1;3;4;5;6];[2;3;4;5;6]];;
|
||||||
|
]}
|
||||||
|
invariant: [cartesian_product l = map_product id l].
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val map_product_l : ('a -> 'b list) -> 'a list -> 'b list list
|
||||||
|
(** [map_product_l f l] maps each element of [l] to a list of
|
||||||
|
objects of type ['b] using [f].
|
||||||
|
We obtain [[l1;l2;…;ln]] where [length l=n] and [li : 'b list].
|
||||||
|
Then, it returns all the ways of picking exactly one element per [li].
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val diagonal : 'a t -> ('a * 'a) t
|
val diagonal : 'a t -> ('a * 'a) t
|
||||||
(** All pairs of distinct positions of the list. [list_diagonal l] will
|
(** All pairs of distinct positions of the list. [list_diagonal l] will
|
||||||
return the list of [List.nth i l, List.nth j l] if [i < j]. *)
|
return the list of [List.nth i l, List.nth j l] if [i < j]. *)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue