How do I compute the cartesian product of n sequences in F#?

前端 未结 3 1313
[愿得一人]
[愿得一人] 2020-12-06 01:43

I was given a puzzle as a present. It consists of 4 cubes, arranged side by side. The faces of each cube are one of four colours.

To solve the puzzle, the cubes must

相关标签:
3条回答
  • 2020-12-06 02:05

    Here's a first try at a list version. I think it could be cleaned up a bit.

    let rec cart nll = 
      let f0 n nll =
        match nll with
        | [] -> [[n]]
        | _ -> List.map (fun nl->n::nl) nll
      match nll with
      | [] -> []
      | h::t -> List.collect (fun n->f0 n (cart t)) h
    
    0 讨论(0)
  • 2020-12-06 02:10

    Use recursion: the cartesian product of n lists {L1..LN} is the collection of lists you get when you add each element in L1 to each sublist in the cartesian product of lists {L2..LN}.

    let rec cart1 LL = 
        match LL with
        | [] -> Seq.singleton []
        | L::Ls -> seq {for x in L do for xs in cart1 Ls -> x::xs}
    

    Example:

    > cart1 [[1;2];[3;4;5];[6;7]] |> Seq.toList;;
    val it : int list list =
      [[1; 3; 6]; [1; 3; 7]; [1; 4; 6]; [1; 4; 7]; [1; 5; 6]; [1; 5; 7]; [2; 3; 6];
       [2; 3; 7]; [2; 4; 6]; [2; 4; 7]; [2; 5; 6]; [2; 5; 7]]
    

    The cartesian product of [1;2] [3;4;5] and [6;7] is the union of {1 appended to each list in cart [[3;4;5];[6;7]]} and {2 appended to each list in cart [[3;4;5];[6;7]]}. This is the second clause in the match statement.

    0 讨论(0)
  • 2020-12-06 02:22

    Here's a solution 'a list list -> Seq<'a list> to calculate the Cartesian product of n lists, with lazy evaluation. I wrote it to be an F# analogue of Python's itertools.product

    let product lists = 
        let folder list state =
             state |> Seq.allPairs list |> Seq.map List.Cons 
        Seq.singleton List.empty |> List.foldBack folder lists
    

    It's based on List.allPairs which was introduced in F# 4.0.

    0 讨论(0)
提交回复
热议问题