Check if a matrix contains a number - ocaml

I want to check if a matrix of type [[a,b,c][d,e,f]] contains a specific number.
I'm having trouble accessing the list inside the list.
let matrix = [[1;2;3]; [4;5;6]];;
let rec contains mat x = match mat with
| [] -> false
| h::t -> if (h=x) then true else contains t x;;
This work on a one-dimensional list, but I'm just too much of a newbie to get it to work on a two-dimensional.

First off, your function contains is List.mem in the standard library (not that there is anything wrong with reimplementing it to learn OCaml).
Also, if (h=x) then true else contains t x is usually written (h=x) || contains t x.
As for your problem, you need to iterate over each sublist of the matrix (presumably representing a row), and for each row check if it contains the number you're looking for :
# let rec mat_contains mat x = match mat with
| [] -> false
| row::tl -> contains row x || mat_contains tl x;;
val mat_contains : 'a list list -> 'a -> bool = <fun>
# mat_contains matrix 4;;
- : bool = true
As an aside, here it is written using functions in the standard library :
# let mat_contains2 mat x = List.exists (List.mem x) mat;;
val mat_contains2 : 'a list list -> 'a -> bool = <fun>
# mat_contains2 matrix 4;;
- : bool = true

Related

Determine if a matrix is square OCaml

I'm working on a problem where they ask us to write a function to determine if a matrix is square (n by n, for any n >= 0) with OCaml
I have a type matrix already defined
type matrix = float list list
Also I previously have a function that works to determine the length of a list
let rec length (l : 'a list): int =
match l with
| [] -> 0
| _ :: xs' -> 1 + length xs'
Right now I'm thinking about writing a helper function which checks if the length of all rows are equal
let rec check_row_equal (m : matrix): bool =
match m with
| [] -> true
| h1 :: h2 :: t ->
if length h1 <> length h2 then false
else check_row_equal (h2 :: t)
But when I ran this function in utop, it says Match_failure ("//toplevel//", 2, 2). If I have this helper function running correctly, my thought for my next function would be
let rec is_square (m : matrix): bool =
let l = length m in
if check_row_equal m == false then false
else if (l != the length of one of the rows) then false
else true
I haven't figured out how to calculate the length of the row, maybe another helper function like
let row_length (m : matrix): int =
match m with
| [] -> 0
| h :: t -> length h
But again, I need help with the check_row_equal function, please help me to fix that, thank u!
let rec check_row_equal (m : matrix): bool =
match m with
| [] -> true
| h1 :: h2 :: t ->
if length h1 <> length h2 then false
else check_row_equal (h2 :: t)
You're getting a match error because you have a case for an empty list, and a list with two or more elements, but not a list with one element. Presumably if there is only one row, this should return true.
Incorporating this and simplifying the code a bit.
let rec check_row_equal (m : matrix): bool =
match m with
| [] | [_] -> true
| h1 :: (h2 :: _ as tl) ->
length h1 = length h2 && check_row_equal tl
You don't say what it means specifically to check whether a matrix is square. I'll assume you want to check the lengths of all the contained lists to make sure they're the same, and this should also be the same as the length of the outer list.
Here are a couple of comments:
Your length function works correctly in the abstract, but it doesn't work for the normal kind of OCaml list. In OCaml, the empty list (the final tail of every list) looks like [] and Cons (a, b) looks like a :: b. Maybe your code is supposed to work with a custom list type, but then it's confusing to name it list, like the normal OCaml list.
You already have a function length that visits every element of a list and calculates an answer. You need a function just like this except that each element of the list is another list, and you want to determine whether the lengths of these are all the same. Just as your length function gets a new result by adding 1 to the returned result, you can figure out an operation that tracks whether the lists have all been the same length so far and, if so, what that length was.
I hope this helps. I don't want to write code for you because this is an assignment.

OCaml : filter map and put the values into a list

I can filter my map by key :
module PairKeys =
struct
type t = string * string
let compare (x0,y0) (x1,y1) =
match String.compare x0 x1 with
| 0 -> String.compare y0 y1
| c -> c
end
module StringMap = Map.Make(PairKeys);;
....
let put_key_values_into_a_list (key_searched : string) =
StringMap.filter (fun key -> key = key_searched)
(* should return a list of the values in the filtered map *)
After that, I want to put the values into a list.
How can I do this in OCaml?
Map.Make documentation :
http://caml.inria.fr/pub/docs/manual-ocaml/libref/Map.Make.html
Thanks
You can use bindings to retrieve the key/value pairs of a map and then further process them to extract the values. For example:
let put_key_values_into_a_list key_searched map =
MyMap.filter (fun key _ -> key = key_searched) map
|> MyMap.bindings |> List.split |> snd
We use List.split to convert a list of pairs into a pair of lists (one containing the keys, one the values) and then snd to extract the list of values.
Note also that filter takes a function with two arguments (the second of which gets ignored here).
Here is how I did it. I called fold after filter :
let put_key_values_into_a_list key_searched map =
MyMap.fold (fun _ i acc -> i::acc)
(MyMap.filter (fun (x,_) _ -> x = key_searched) map)
[]

Information hiding with OCaml records

Given
type 'a set = { insert : 'a -> 'a set; contains : 'a -> bool }
How can I implement
val empty : 'a set
?
I've tried closing over something, say a list, but the return type is wrong.. since it is. (ignoring the fact that the performance characteristics here are terrible :-) )
let empty =
let rec insert_f set a =
match set with
| [] -> a :: []
| k :: rest ->
if k = a then
k :: rest
else
k :: insert_f rest a
in
let rec contains_f set a =
match set with
| [] -> false
| k :: rest ->
if k = key then
true
else contains_f rest a
in
{ insert = insert_f []; contains = contains_f []}
directly writing the empty is not the easiest in such data structure, as you will need to write the insert, which will contains again an insert and so one... So let's write first the insert:
let rec insert : 'a set -> 'a -> 'a set = fun s x -> {
insert = (fun y -> failwith "TODO");
contains = (fun y -> if x = y then true else s.contains y) }
in insert, you want to recursively call insert, but the first parameter will be the record you are writing. So here is the complete solution:
let rec insert : 'a set -> 'a -> 'a set = fun s x ->
let rec ss = {
insert = ( fun y -> insert ss y);
contains = (fun y -> if x = y then true else s.contains y)}
in ss
let rec empty = {
insert = (fun x -> insert empty x);
contains = (fun x -> false)}
First of all, it's bool, not boolean. :)
Second, this definition is quite cumbersome. But you can do something like:
let empty = {
insert=(fun x -> {
insert=(fun x -> assert false);
contains=(fun x-> assert false)});
contains=(fun x -> false)}
with your implementations of insert and contains for non-empty sets in place of "assert false" of course.
A hint for implementing insert and contains: don't use any lists, use compositions of a functions from existing and new sets.
You can find nice examples in e.g. "On Understanding Data Abstraction, Revisited" by W. Cook, that paper is available online.

Haskell Split list into Sublist using pattern recognition

I am trying to split a Array containing I and Os, if a certain pattern occurs.
lets assume i have an input, looking like this:
data Bit = O | I deriving (Eq, Show)
let b = [I,I,O,O,O,O,O,I,I,O,O,O,I,O]
that is what i am generating, when encoding [[Bool]] -> [Bit] corresponding input to my encode function would be let a = [[True, False, False, True],[False, False],[False]]
Now my objective is to decode what ive generated,so i need a function that gets me from b to a.
But i can't come up with a way to split b list into 3 sublists, every time it reads either I,O or I,I. Every Odd letter stands for following member or starting array member. I am basically copying utf unicode encoding.
So i am trying to build a function that would get me from b to a.
After some time i came up with this:
split :: [Bit] -> [[Bit]]
split (x1:x2:xs) = if (x1 == I)
then [x2 : split xs]
else x2 : split xs
And i cant figure out, how to split the list into sublist. Any kind of advice/help/code is greatly appreciated
EDIT:
split :: [Bit] ->[[Bit]]
split [] = []
split xs = case foo xs of (ys,I,x2) -> -- generate new subarray like [...,[x2]]
(ys,O,x2) -> -- append existing subarray with value x2 [.....,[previous values]++x2]
foo :: [a] -> ([a],x1,x2)
foo x1:x2:input = (input,x1,x2)
those 2 comments are the last thing i need to figure out. after that im done :)
if feeding b into function split, i want this ouput: [[I,O,O,I],[O,O],[O]]
final step would be to get from b to [[True, False, False, True],[False, False],[False]]
I would start with if (x1 == 1) ...
If x1 is a Bit that can be either I or O, why are you comparing its equality against a Num, 1?
If I got it right, you need something like:
split [] = []
split xs = case foo xs of (ys,r) -> r : split ys
foo :: [a] -> ([a],r)
foo = undefined
In foo, the list should get partially consumed and returns the rest of the list and the value to collect.
EDIT:
data Bit = O | I deriving (Eq, Show)
sampleA = [[True, False, False, True],[False, False],[False]]
sampleB = [I,I,O,O,O,O,O,I,I,O,O,O,I,O]
type TwoBit = (Bit,Bit)
twobit (x:y:xs) = (x,y) : twobit xs
twobit _ = []
split :: [TwoBit] -> [[Bool]]
split [] = []
split xs = case spli xs of (ys,r) -> r : split ys
where
spli :: [TwoBit] -> ([TwoBit],[Bool])
spli (x:xs) = case span (not . pterm) xs of
(ys,zs) -> (zs, map ptrue $ x:ys)
pterm x = (I,O) == x || (I,I) == x
ptrue x = (O,I) == x || (I,I) == x
splitTB = split . twobit
main = print $ splitTB sampleB == sampleA
PS Functions that look like s -> (s,a) could also be represented as State monad.

Returning first value of list of tuples

I'm learning to deal with Lists and Tuples in F# and a problem came up. I have two lists: one of names and one with names,ages.
let namesToFind = [ "john", "andrea" ]
let namesAndAges = [ ("john", 10); ("andrea", 15) ]
I'm trying to create a function that will return the first age found in namesAndAges given namesToFind. Just the first.
So far I have the following code which returns the entire tuple ("john", 10).
let findInList source target =
let itemFound = seq { for n in source do
yield target |> List.filter (fun (x,y) -> x = n) }
|> Seq.head
itemFound
I tried using fst() in the returning statement but it does not compile and gives me "This expression was expected to have type 'a * 'b but here has type ('c * 'd) list"
Thanks for any help!
There are lots of functions in the Collections.List module that can be used. Since there are no break or a real return statement in F#, it is often better to use some search function, or write a recursive loop-function. Here is an example:
let namesToFind = [ "john"; "andrea" ]
let namesAndAges = [ "john", 10; "andrea", 15 ]
let findInList source target =
List.pick (fun x -> List.tryFind (fun (y,_) -> x = y) target) source
findInList namesToFind namesAndAges
The findInList function is composed of two functions from the Collections.List module.
First we have the List.tryFind predicate list function, which returns the first item for which the given predicate function returns true.
The result is in the form of an option type, which can take two values: None and Some(x). It is used for functions that sometimes give no useful result.
The signature is: tryFind : ('T -> bool) -> 'T list -> 'T option, where 'T is the item type, and ('T -> bool) is the predicate function type.
In this case it will search trough the target list, looking for tuples where the first element (y) equals the variable x from the outer function.
Then we have the List.pick mapper list function, which applies the mapper-function to each one, until the first result that is not None, which is returned.
This function will not return an option value, but will instead throw an exception if no item is found. There is also an option-variant of this function named List.tryPick.
The signature is: pick : ('T -> 'U option) -> 'T list -> 'U, where 'T is the item type, 'U is the result type, and ('T -> 'U option) is the mapping function type.
In this case it will go through the source-list, looking for matches in the target array (via List.tryFind) for each one, and will stop at the first match.
If you want to write the loops explicitly, here is how it could look:
let findInList source target =
let rec loop names =
match names with
| (name1::xs) -> // Look at the current item in the
// source list, and see if there are
// any matches in the target list.
let rec loop2 tuples =
match tuples with
| ((name2,age)::ys) -> // Look at the current tuple in
// the target list, and see if
// it matches the current item.
if name1 = name2 then
Some (name2, age) // Found a match!
else
loop2 ys // Nothing yet; Continue looking.
| [] -> None // No more items, return "nothing"
match loop2 target with // Start the loop
| Some (name, age) -> (name, age) // Found a match!
| None -> loop rest // Nothing yet; Continue looking.
| [] -> failwith "No name found" // No more items.
// Start the loop
loop source
(xs and ys are common ways of writing lists or sequences of items)
First let's look at your code and annotate all the types:
let findInList source target =
let itemFound =
seq {
for n in source do
yield target |> List.filter (fun (x,y) -> x = n) }
|> Seq.head
itemFound
The statement yield List.Filter ... means you're creating a sequence of lists: seq<list<'a * 'b>>.
The statement Seq.head takes the first element from your sequence of lists: list<'a * 'b>.
So the whole function returns a list<'a * 'b>, which is obviously not the right type for your function. I think you intended to write something like this:
let findInList source target =
let itemFound =
target // list<'a * 'b>
|> List.filter (fun (x,y) -> x = n) // list<'a * 'b>
|> Seq.head // 'a * 'b
itemFound // function returns 'a * 'b
There are lots of ways you can get the results you want. Your code is already half way there. In place of filtering by hand, I recommend using the built in val Seq.find : (a' -> bool) -> seq<'a> -> 'a method:
let findAge l name = l |> Seq.find (fun (a, b) -> a = name) |> snd
Or you can try using a different data structure like a Map<'key, 'value>:
> let namesAndAges = [ ("john", 10); ("andrea", 15) ] |> Map.ofList;;
val namesAndAges : Map<string,int> = map [("andrea", 15); ("john", 10)]
> namesAndAges.["john"];;
val it : int = 10
If you want to write it by hand, then try this with your seq expression:
let findInList source target =
seq {
for (x, y) in source do
if x = target then
yield y}
|> Seq.head
Like fst use this(below) . This way you can access all the values.
This is from F# interactive
let a = ((1,2), (3,4));
let b = snd (fst a);;
//interactive output below.
val a : (int * int) * (int * int) = ((1, 2), (3, 4))
val b : int = 2