-
- let enum_cartesian_product ll =
- let pool = Array.map Array.of_list (Array.of_list ll) in
- let n = Array.length pool in
- let indices = Array.make n 0
- and lengths = Array.map (fun a -> Array.length a - 1) pool in
- let rec update_indices = function
- | i when indices.(i) <> lengths.(i) ->
- indices.(i) <- indices.(i) + 1
- | 0 -> raise BatEnum.No_more_elements
- | i ->
- indices.(i) <- 0; update_indices (i - 1)
- in
- let is_first = ref true in
- let next () =
- if !is_first then
- is_first := false
- else update_indices (n - 1);
- Array.to_list (BatArray.map2 Array.get pool indices)
- in
- BatEnum.from next
-
-
- let combinations l r =
- if r <= 0 then
- invalid_arg "r must be positive";
- let pool = Array.of_list l
- and indices = Array.init r (fun x -> x) in
- let n = Array.length pool in
- let rec next_i = function
- | i when indices.(i) <> i + n - r -> i
- | 0 -> raise BatEnum.No_more_elements
- | i -> next_i (i - 1)
- in
- let is_first = ref true in
- let next () =
- if !is_first then
- is_first := false
- else begin
- let i = next_i (r - 1) in
- indices.(i) <- indices.(i) + 1;
- for j = i + 1 to r - 1 do indices.(j) <- indices.(j - 1) + 1 done
- end;
- map (Array.get pool) (Array.to_list indices)
- in
- BatEnum.from next
-