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!
Related
Trying to insert a number in all positions of the list, result being a list of lists.
something like:
insert 4 [1; 2; 3] = [[4; 1; 2; 3]; [1; 4; 2; 3]; [1; 2; 4; 3]; [1; 2; 3; 4]]
My idea is to apply Map on the list with a function that returns a list.
resulting in list of lists. like [f 1; f 2 ; f3] (I know will only have 3 lists, but just want to get this working first)
let insert (x : 'a) (ls : 'a list): 'a list list =
let aux p =
List.fold_left
(fun f2 acc q ->
if p = q then List.append acc x::[q]
else List.append acc q::[])
[] ls
in
List.map aux ls
Hope is, function aux will return a list with x inserted in the right place.
The problem is, List.map f1 ls line is assuming ls is 'a list list even though it is defined as 'a list
Any ideas please?
To actually answer your question, instead of providing you with different methods to reach your goal (you wanted to know what is actually wrong with your code, not how one could solve the problem.):
signature of fold_left is ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a = <fun>. Instead of ('a -> 'b -> 'a) your provide it with fun f2 acc q -> ... = ('a -> 'b -> 'c -> 'a). Just remove the f2 and you're fine.
put brackets around stuff like x::[q], or use ##.
Your code:
let insert (x : 'a) (ls : 'a list): 'a list list =
let aux p =
List.fold_left
(fun f2 acc q ->
if p = q then List.append acc x::[q]
else List.append acc q::[])
[] ls
in
List.map aux ls
Working code:
let insert (x : 'a) (ls : 'a list): 'a list list =
let aux p =
List.fold_left
(fun acc q ->
if p = q then List.append acc (x::[q])
else List.append acc (q::[]))
[] ls
in
List.map aux ls
For input insert 4 [1;2;3]this returns int list list = [[4; 1; 2; 3]; [1; 4; 2; 3]; [1; 2; 4; 3]]. This is almost what you wanted. The rest can be fixed by you :).
Note:
The Error that the Compiler throws is: Error: This expression has type 'a list but an expression was expected of type 'b list -> 'b list list. For the next time, just think about what happened. You provide fold_left with ('a -> 'b -> 'c -> 'a); which is not "wrong", but not what you want. You could write it as ('a -> ('b -> 'c) -> 'a). This means the acc-value is some 'a and the value of the fold is a function 'b -> 'c. This explains the error-message :).
Try breaking this problem down.
First hurdle: can you insert an element at a given index in a list? The start might look like:
let rec insert lst pos v =
(* ... *)
Well, we know if the position is 0, it should go at the front.
let rec insert lst pos v =
match pos with
| 0 -> v :: lst
| _ -> (* ... *)
If it's not 0 then you'd need to append the first element in lst to the result of inserting into the tail of the list at pos - 1.
Of course, the devil is in the details. What happens if you try insert [1; 2; 3; 4] 7 5? You need to find a way to check for situations like this.
If you can get this function to work, you then just need to iterate from 0 to the length of the list, inserting the new value into the list.
List.init would work nicely.
List.(
let lst = [1; 2; 3; 4] in
let len = length lst + 1 in
init len (fun i -> insert lst i 5)
)
And as a result, if you wrote insert correctly, you should get:
[[5; 1; 2; 3; 4]; [1; 5; 2; 3; 4]; [1; 2; 5; 3; 4];
[1; 2; 3; 5; 4]; [1; 2; 3; 4; 5]]
This should do the trick:
let rec insert v l =
match l with
| [] -> [[v]]
| x::xs -> (v::l) :: (List.map (List.cons x) (insert v xs))
Adding an explanation, had to think about this a while too:
For an empty list there is only one way to insert v and [[v]] is the result.
For a list x::xs first insert v at all positions in xs: insert v xs, which gives a list of lists. Then for each list add x back to the front: List.map (List.cons x) .... This gives all the results where v is inserted after x. So last construct the list where v is added before x: v::l. Adding that to the front of the list of lists gives the final result.
I've been trying to add a list to a list of lists.
What I want :
l1 : [[]] / [] / Empty list
l2 : [1;2]
result : [[1;2]]
add [1;3] to result :
result : [[1; 2]; [1; 3]]
I've tried to play with the # and the :: operator for quite a while now, still no results.
Here's my problem :
type sign = Neg | Zero | Pos | Error
let all_pairs (l1: sign list) (l2 : sign list) : sign list list =
let rec aux acc list =
match list with
| [] -> acc
| hd :: tl ->
let rec m_aux m_acc m_list =
match m_list with
| [] -> aux (m_acc :: acc) tl
| m_hd :: m_tl -> m_aux (m_hd :: m_acc) m_tl
in m_aux [hd] l2
in aux [] l1
With a given L1, L2 which are sign list, return a sign list list with every combination of two signs x and y, x is in L1 and y is in L2
Example :
L1 : [Pos; Error]
L2 : [Neg; Zero]
all_pairs L1 L2 should return
[ [Pos; Neg]; [Pos; Zero]; [Error; Neg]; [Error; Zero] ]
In this exact order
I don't understand your first line. But here's a session showing how to build up the results you seem to be asking for:
# let l1 = [];;
val l1 : 'a list = []
# let l2 = [1;2];;
val l2 : int list = [1; 2]
# let result1 = l1 # [l2];;
val result1 : int list list = [[1; 2]]
# let l3 = [1;3];;
val l3 : int list = [1; 3]
# let result2 = result1 # [l3];;
val result2 : int list list = [[1; 2]; [1; 3]]
A problem is that you're trying to extend your lists at the end. This isn't natural (or efficient) in OCaml. If you think about a adding new value to the beginning of a list things are simpler.
# let result3 = l3 :: l1;;
val result3 : int list list = [[1; 3]]
# let result4 = l2 :: result3;;
val result4 : int list list = [[1; 2]; [1; 3]]
The :: operator adds a new value to the beginning of a list. There's no single operator for adding to the end of a list (because it's not natural or efficient).
Update
You can code your function like this:
let all_pairs l1 l2 =
List.concat
(List.map
(fun a -> List.map (fun b -> [a;b]) l2)
l1)
It works for me.
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.
I have a function that returns every "sublists" from a given list:
let rec sublists = function
[] -> [[]]
| h::t -> let st = sublists t in
List.map (function l -> h::l) st # st;;
For example, if you try
sublists [1;4;9;12]
it will return:
[[1; 4; 9; 12]; [1; 4; 9]; [1; 4; 12]; [1; 4]; [1; 9; 12]; [1; 9]; [1; 12];
[1]; [4; 9; 12]; [4; 9]; [4; 12]; [4]; [9; 12]; [9]; [12]; []]
That are every possible combinations of elements in the list (order doesn't matter)
I have to do a function that returns a different sublists pair that fulfill a given property.
Function must have this type: ('a list -> 'a list -> bool) -> 'a list -> 'a list * 'a list
For example, if we have the previous list and we try
search (<4) [1;4;9;12]
It will return:
([9;12], [9]) because these lists satisfaces the given condition (<4). Order does not matter, it could return ([9], [12]) instead, or another possible combination.
I'm stucked at this, I have done a function that check if a given list is a sublist of another list:
let is_sublist_of l1 l2 =
let sub = sublists l1 in
List.mem l2 sub;;
But I think that is useless here. Coul anyone help me?
Can't you just filter the list first and then apply the two first runs of sublist to it ?
let filter_sublist f l =
let l = List.filter f l in
let rec sublists = function
| [] -> [], []
| h :: t ->
let st1, st2 = sublists t in
h :: st1, st2
in sublists l
The problem here is that f is of type 'a -> bool because I don't understand your type ('a list -> 'a list -> bool). What is it supposed to represent ?
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*)
;;