mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-07 19:55:31 -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 ->
|
||||
List.fold_left
|
||||
(fun acc x2 -> f acc x1 x2)
|
||||
acc l2
|
||||
) acc l1
|
||||
acc l2)
|
||||
acc l1
|
||||
|
||||
let diagonal l =
|
||||
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 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 rec recurse cmp acc l1 l2 = match l1,l2 with
|
||||
| [], _ -> 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
|
||||
(** 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
|
||||
(** 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]. *)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue