Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

transpose of a list of lists

Tags:

ocaml

I'm trying to make a recursive function to get the transpose of a list of lists, n x p to p x n. But i'm unable to do so. I've been able to make a function to transpose a 3 x n list of lists to an n x 3 one:

let rec drop1 list=
    [(match (List.nth list 0) with [] -> [] | a::b -> b);
     (match (List.nth list 1) with [] -> [] | a::b -> b);
     (match (List.nth list 2) with [] -> [] | a::b -> b);]

let rec transpose list=
    if List.length (List.nth list 0) == 0 then []
    else [(match (List.nth list 0) with [] -> 0 | a::b -> a);
          (match (List.nth list 1) with [] -> 0 | a::b -> a);
          (match (List.nth list 2) with [] -> 0 | a::b -> a)]
         :: transpose (drop1 list)

But I'm not able to generalize it. I'm surely thinking in the wrong direction. Is this generalizable? Is there a better solution? Please help.

like image 284
lalli Avatar asked Oct 21 '10 16:10

lalli


2 Answers

let rec transpose list = match list with
| []             -> []
| []   :: xss    -> transpose xss
| (x::xs) :: xss ->
    (x :: List.map List.hd xss) :: transpose (xs :: List.map List.tl xss)

Taking advantage of syntax changes since answer first posted:

let rec transpose list = match list with
| []             -> []
| []      :: xss -> transpose xss
| (x::xs) :: xss ->
    List.(
      (x :: map hd xss) :: transpose (xs :: map tl xss)
    )
like image 50
sepp2k Avatar answered Nov 09 '22 11:11

sepp2k


I know this is an old question, but I recently had to solve this as part of an exercise I was doing, and I came across @sepp2k's solution, but I couldn't understand how it worked, so I tried to arrive at it by myself.

This is essentially the same algorithm, but a little bit more terse, as it does not destructure the list of lists. I thought I would post it here in case anyone else is searching, and might find this way of expressing it useful:

let rec transpose = function
   | [] 
   | [] :: _ -> []
   | rows    -> 
       List.map List.hd rows :: transpose (List.map List.tl rows)
like image 28
naartjie Avatar answered Nov 09 '22 10:11

naartjie