Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cartesian product two lists [duplicate]

Possible Duplicate:
F# - cross product of two lists
Projecting a list of lists efficiently in F#

I have a function that takes two integer lists and returns a single list with all the cartesian products. I think i have the correct idea but not the right implementation. Can I get some pointers?

let rec cartesian = function
 | ([],[]) -> []
 | (xs,[]) -> []
 | ([],ys) -> []
 | (x::xs,ys) ->   List.map(fun y -> (x,y)::[]) cartesian (xs,ys) 
like image 985
user1072706 Avatar asked Feb 09 '12 15:02

user1072706


People also ask

Can Cartesian product have duplicates?

Cartesian product does not have existence without set. And, a set cant have duplicate elements. So there is no chance of getting a duplicate in case of cartesian product.

How do you find the Cartesian product of two lists in Python?

Practical Data Science using Python We have to find Cartesian product of these two lists. As we know if two lists are like (a, b) and (c, d) then the Cartesian product will be {(a, c), (a, d), (b, c), (b, d)}. To do this we shall use itertools library and use the product() function present in this library.

What is the Cartesian product of 3 sets?

Note: A × A × A = {(a, b, c) : a, b, c ∈ A}.

What is Cartesian product in C++?

The Cartesian product of two sets is. A x B = {a, d}, {a, e}, {a, f}, {b, d}, {b, e}, {b, f}, {c, d}, {c, e}, {c, f}} A has 3 elements and B also has 3 elements. The Cartesian Product has 3 x 3 = 9 elements.


1 Answers

This is a quick fix:

let rec cartesian = function
 | ([],[]) -> []
 | (xs,[]) -> []
 | ([],ys) -> []
 | (x::xs, ys) -> (List.map(fun y -> x,y) ys) @ (cartesian (xs,ys))

The idea is that with each element x, you generate a list [(x, y1); (x, y2); ...; (x, yn)] and concatenate those lists altogether.

In your function, the first pattern matching case is redundant. And the arguments are more convenient to be in the curried form. The function could look like this:

let rec cartesian xs ys = 
  match xs, ys with
  | _, [] -> []
  | [], _ -> []
  | x::xs', _ -> (List.map (fun y -> x, y) ys) @ (cartesian xs' ys)

Once you understand the idea, you can see that the high-order function List.collect perfectly matches the task:

let cartesian xs ys = 
    xs |> List.collect (fun x -> ys |> List.map (fun y -> x, y))
like image 108
pad Avatar answered Sep 30 '22 20:09

pad