1

I am trying to take three lists of strings and have the code return a list interleaving the three. If the lists have unequal sizes then we use "-" to indicate a value is missing.

For example:

interleave3 ["1"; "2"; "3"] ["4"] ["5"; "6"]

should return:

["1"; "4"; "5"; "2"; "-"; "6"; "3"; "-"; "-"]
glennsl
  • 28,186
  • 12
  • 57
  • 75
Adrien Aacha
  • 109
  • 2
  • 8
  • 1
    I suggest you be more flexible in what tutorials you look at :-) Almost any tutorial that explains how to write a simple recursive function will be applicable to your problem. After you've written some code you can come back to StackOverflow with a more specific question. – Jeffrey Scofield Oct 29 '17 at 22:23

2 Answers2

2

If the task had been to just interleave the elements until all the lists are empty it would have been fairly straightforward; just rotate the lists while appending one element at a time until they're all empty.

let rec interleave3 xs ys zs =
  match xs, ys, zs with
  | [], [], [] -> []
  | [], ys, zs -> "-" :: interleave3 ys zs []
  | x::xs, ys, zs -> x :: interleave3 ys zs xs

However, since the requirement is that each list should effectively be padded out to equal length, we need to somehow keep track of how long the longest list is, and continue padding the resulting list until very list has been padded out. One way of doing so is to keep a total count, and continue going even after we're done, until the total is divisible by 3, at which point we know the resulting list has an equal number of elements:

let interleave3 xs ys zs =
  let rec aux xs ys zs n =
    match xs, ys, zs with
    | [], [], [] when n mod 3 = 0 -> []
    | [], [], []    -> "-" :: aux [] [] [] (n+1)
    | [], ys, zs    -> "-" :: aux ys zs [] (n+1)
    | x::xs, ys, zs ->   x :: aux ys zs xs (n+1)
  in aux xs ys zs 0
glennsl
  • 28,186
  • 12
  • 57
  • 75
1

I would suggest to try with two lists,and then you go for 3 or more lists. Once you understand the pattern for two then you can extend the same concept for more lists. I have written a quick solution, but I don't claim it is idiomatic OCaml. Also list in OCaml is semicolon separated.

let rec patternMatching xs ys zs = 
        match xs, ys, zs with
        | [], [], [] -> []
        | x::xs, [], [] -> x :: "-" :: "-" :: patternMatching xs [] []
        | [], y::ys, [] -> "-" :: y :: "-" :: patternMatching [] ys []
        | [], [], z::zs -> "-" :: "-" :: z :: patternMatching [] [] zs
        | x::xs, y::ys, [] -> x :: y :: "-" :: patternMatching xs ys []
        | x::xs, [], z::zs -> x :: "-" :: z :: patternMatching xs [] zs
        | [], y::ys, z::zs -> "-" :: y :: z :: patternMatching [] ys zs
        | x::xs, y::ys, z::zs -> x :: y :: z :: patternMatching xs ys zs



       # patternMatching  ["1"; "2"; "3"] ["4"] ["5"; "6"];;
- : string list = ["1"; "4"; "5"; "2"; "-"; "6"; "3"; "-"; "-"]                    
keep_learning
  • 1,057
  • 5
  • 14