I have to solve this exercise in OCaml : Write a recursive function that repeats the values of a list, for exemple repeat [3;2;4;5] should give [3;2;2;4;4;4;5;5;5;5]
I think that I should use match with and concatenate but I really have no idea how to start this exercise…
It seems like you want to repeat the nth element (n+1) times (remember indexes start at 0).
I think that I should use match with and concatenate
Not bad intution, if you were to use an imperative approach that could work.
I got it to work like this:
utop # let repeat ls =
(* `helper` will just repeat `l` n times *)
let rec helper acc n l =
if n = 0
then acc
else helper (l @ acc) (n-1) l in
(* `mapi` to know the position of the element, `flatten`
build a single list out of many *)
List.flatten @@ List.mapi (fun i x -> helper [] (i+1) [x]) ls ;;
val repeat : 'a list -> 'a list = <fun>
utop # repeat [3;2;4;5] ;;
- : int list = [3; 2; 2; 4; 4; 4; 5; 5; 5; 5]
This builds a list of lists and then flattens it. Not the best code but seems to work like you want it to
For a given list, map each element to a list of n + 1 elements, where n is the zero-based index of the element
Flatten the resulting list of lists of ints, into a list of ints.
I actually could have sworn there was a List.flat_map, which allowed doing this in an even more succinct way, but it looks like it’s not in the published library yet.
let repeat_values l =
List.mapi (fun i v -> List.init (i + 1) (fun _ -> v)) l
|> List.concat
for a standard library quick solution. If you want a more efficient solution, you should probably write your own recursive function, a kind of custom List.fold_left.
I found a solution ! let rec inter l = match l with |[]->[] |p::q->p::q@(inter q) ;; (* # inter [1;2;3;4];; - : int list = [1; 2; 3; 4; 2; 3; 4; 3; 4; 4] *)
Then I just sorted this list and It works