How can I add an element into a int list list?
|x::y::xs-> if(x<=y)
then [x]#(ordina (y::xs))
else [x]::ordina (y::xs)
I tried with this, but it didn't work..
To add a new int list containing x to the head of an int list list:
# let x = 14 in
let ill = [[3;4]; [5;6]] in
[x] :: ill ;;
- : int list list = [[14]; [3; 4]; [5; 6]]
You can also write this:
# let x = 14 in
let ill = [[3;4]; [5;6]] in
[[x]] # ill ;;
- : int list list = [[14]; [3; 4]; [5; 6]]
But this entails a tiny amount of unnecessary work.
As a side comment, the two branches of your if look like they're trying to do the same thing. If you want the result to be [[14; 3; 4]; [5; 6]] you need to write a little more code to destructure the int list list.
# let x = 14 in
let ill = [[3;4]; [5;6]] in
match ill with
| [] -> [[x]]
| h :: t -> (x :: h) :: t ;;
- : int list list = [[14; 3; 4]; [5; 6]]
Related
Given a list: [1; 2; 3], how can I generate all possible splits:
[
[ [1; 2; 3] ];
[ [1]; [2; 3] ];
[ [1]; [2]; [3] ];
[ [1; 2]; [3] ]
]
I have no real attempt yet, I don't know how to start
EDIT : attempt
I tried to do it step by step but it's kinda messy
and I couldn't do mergeFirst, without mergeFirst it gives : [[[1]; [2; 3]]; [[1]; [2]; [3]]]
Am I on the right path ? I don't think my code will work if the list contains more than 3 elements too ...
let split = function
| [] -> []
| x::y -> [[x::y]] # [[[x]] # [[List.hd y]]]
(* let mergeFirst a = function
... *)
let addtoseperatelist a list =
List.map (fun t -> [[a]] # t) (list)
let rec generateAllSplit = function
| [] -> []
| [x;y] -> split (x::y::[])
| x::y -> addtoseperatelist x (generateAllSplit y) # (mergeFirst x (generateAllSplit y))
let myList = [[1;2;3]]
let _ = generateAllSplit myList
Until you get farther with your analysis, this isn't actually an OCaml question. It's more a question about breaking down a problem recursively.
One good way to solve problems that feel recursive is to imagine that you already had the solution. If you had your split function already, it would return the following for the tail of your list ([2; 3]):
[ [[2; 3]]; [[2]; [3]] ]
Is there a way to process this smaller result into your desired final result? Yes. There are two things you can do with [1]: you can merge it with the first element of the returned lists, or you can add it as a separate list. That gives you the four values of the desired result. You should be able to prove to yourself that his always gives the right answer. (Or maybe it doesn't, you'll have to check.)
If your given list has fewer than 2 elements, the result is obvious. You can probably combine this with the above recursive processing to get the answer.
You are on the right track. The merge first is still missing, which you have to do with pattern matching because the empty list is a special case. In my code that is (function [] -> [[x]] | z::zs -> (x::z)::zs) ys
The one element list is also a special case for split because it only has one result. If you would solve that recursively you would get [[x]; []] and [[x] # []] == [[x]].
Instead of adding to the recursive results and merging to the recursive results and then appending the two resulting lists I decided to use a fold_left and construct the adding and merging of each sub list in parallel. Then you can :: the results instead of append:
let myList = [1;2;3]
let rec split = function
| [] -> [[[]]]
| [x] -> [[[x]]]
| (x : int)::xs ->
List.fold_left
(fun (acc : int list list list) (ys : int list list) ->
([x] :: ys) (* add to separate list *)
:: (function [] -> [[x]] | z::zs -> (x::z)::zs) ys (* merge first *)
:: acc
)
[]
(split xs)
let res = split myList;;
val myList : int list = [1; 2; 3]
val split : int list -> int list list list = <fun>
val res : int list list list =
[[[1]; [2; 3]]; [[1; 2; 3]]; [[1]; [2]; [3]]; [[1; 2]; [3]]]
I have a function:
let rec multiply x ls =
match ls with
[] -> []
| h::tl -> (x * h) :: multiply x tl
multiply 2 [1;2;3] = [2;4;6]
I would like a function that calls multiply from n to 0. I keep having problems because of the base case:
let rec multiply_all x ls = if x > 0
then (multiply n ls) :: multiply_all (n-1) (ls) else ????
I am not sure what to put after the else. I tried to make it
if x > 1 then (multiply n ls) :: multiply_all (n-1) (ls) else multiply all 1.
but that doesn't work.
Putting 1 there certainly doesn't work since multiply_all must return a list. So you need a list (of lists of int) to put there. But which list should it be?
The short answer is that in such simple cases, the list you need is usually the empty list: [].
As a slightly longer answer, we can consider the case for multiply_all 0 in relation to the intended results of multiply_all 1, multiply_all 2, etc., and try to find a pattern that fits. We want multiply_all to behave like this:
# multiply_all 2 [1;2;3];;
- : int list list = [[2; 4; 6]; [1; 2; 3]]
# multiply_all 1 [1;2;3];;
- : int list list = [[1; 2; 3]]
So calling multiply_all with some number N as first argument should give us a list of length N. In particular, multiply_all with N = 0 should give a list of length 0. The list of length 0 is the empty list.
Here is your completed definition:
let rec multiply_all x ls =
if x > 0 then (multiply x ls) :: multiply_all (x-1) (ls) else []
Just an other solution :
let multiply_all n l =
let multiply n= List.map (( * ) n) in
let rec aux i acc =
if i > n then acc
else aux (i+1) (multiply i l :: acc)
in
aux 1 []
;;
Test :
# multiply_all 5 [1;2;3];;
- : int list list =
[[5; 10; 15]; [4; 8; 12]; [3; 6; 9]; [2; 4; 6]; [1; 2; 3]]
First of all, your multiply method is pretty inefficient since it isn't tail recursive. Furthermore, the standard library provides you with tools to make that kind of function easier to write:
let multiply n = List.map (( * ) n);;;
val multiply : int -> int list -> int list = <fun>
multiply 5 [1;2;3];;
- : int list = [5; 10; 15]
Note: Also, use partial application when it doesn't obfuscate your code.
As of multiply_all, I'm not sure how to achieve it without JaneStreet's Core (see this question). However, here is a possible implementation using Core:
open Core.Std;; (*Using Core*)
let multiply_all n l =
let multiples = List.init n ~f:(fun x -> n-x) in (*This doesn't exist in Pervasives*)
List.map multiples ~f:(fun m -> multiply l m);;
val multiply_all : int list -> int -> int list list = <fun>
multiply_all 5 [1;2;3];;
- : int list list = [[5; 10; 15]; [4; 8; 12]; [3; 6; 9]; [2; 4; 6]; [1; 2; 3]]
Hope it helps. I'll keep this answer updated with my findings about List.init.
let rec list_add l i =
match l with
[] -> [i]
| h::t -> h::(list_add t i)
list add for adding each pair of integers from two lists
(Type) list add : int list -> int list -> int list
(Description) list add [a; b; c; ...] [x; y; z; ...] returns [a + x; b + y; c + z; ...]. If one list is longer than the other, the remaining list of elements is appended to the result.
(Example) list add [1; 2] [3; 4; 5] returns [4; 6; 5].
let rec add l1 l2 = match l1 with
[] -> l2
|h::t -> (*you can do the rest*)
;;
Need help!!
Define the function "Is_member," which the first parameter is the given matrix and the second parameter is x: int.
Check if element x is in the matrix1.
val Is_member: int list list -> int -> bool = <fun>
Example:
#let matrix1 = [[1; 2]; [3; 4]];;
#val matrix1 : int list list = [[1; 2]; [3; 4]]
# Is_member matrix1 3;;
- : bool = true
I can reduce your problem to just fill blank spaces:
# matrix1;;
- : int list list = [[1; 2]; [3; 4]]
# is_member 1 matrix1;;
- : bool = true
# let is_member x xs = List.____ (fun acc xs -> acc ____ (List.____ x xs)) false xs;;
val is_member : 'a -> 'a list list -> bool = <fun>
It will be easy for you now!
I'm new to OCaml and attempting to implement List.append as a learning exercise. This is what I have:
let rec append a b =
match (List.rev a) with
[] -> b
| x:: xs -> append xs (x::b)
This seems to work until argument a has more than two elements. Example:
# append [1;2] [3;4]
- : int list = [1; 2; 3; 4]
# append [1;2;3] [4;5;6]
- : int list = [2; 1; 3; 4; 5; 6]
What's going on here? I've checked, and List.rev [1;2;3] returns int list = [3; 2; 1]. I know my implementation is naïve and not (yet) lazy, but it seems like it should work.
If you think about it, you are reversing your first list quite a few times. Probably more than you wanted to.
You can see what's happening if you follow the steps of an example.
append [1; 2; 3] []
(* match binds x to 3, xs to [2; 1] *)
append [2; 1] [3]
(* match binds x to 1, xs to [2] *)
append [2] [1; 3]
(* match binds x to 2, xs to [] *)
append [] [2; 1; 3]
(* done *)