A bush is a tree such that a tree node can have either no children, one child, or two
children nodes. Each tree node stores an instance of a type ‘a. The polymorphic type
‘a bush is defined as follows.
type 'a bush =
None
| One of 'a*'a bush
| Two of 'a*'a bush*’a bush
Write a function print_level : 'a bush -> int -> unit that prints the keys
of bush nodes from the given level defined with the second parameter.
I have been redoing some of the old problems and stumbled on this. I have no idea how to start.
You don't say how the levels are numbered. Assume for simplicity that they're numbered starting with 0 at the root, and the level of a child is 1 more than the level of its parent.
The simplest might be to think recursively. What if you knew the parameter n would always be 0? What would the function look like?
Now assume you want to write your function print_level with its parameter n. Assume you have a function that works for all level values smaller than n. How can you use this other function to solve your problem for level n?
Then the big reveal is that this other function is your function itself, calling itself recursively.
I've sold it. Recursively decreasing n until we reach 0 and printing for every element at that level. Trees are really beautiful to work with.
let rec print_level (tr:'a bush) n =
match tr with
| None -> raise Not_found
| One (v,d) when n = 0 -> print_int v
| Two (v,l,d) when n = 0 -> print_int v
| One (v,d) -> print_level d (n-1)
| Two (v,l,d) -> print_level d (n-1);
print_level l (n-1);;
Related
I have these defined types
type Name = string
type Flow = int
type River = R of Name * Flow * River list
type Tributaries = River list
And i want to declare a function contains n r that returns a boolean value if n is contained in River or any of it's branches/Tributaries. and i've came up with this so far
let rec contains (n:Name)(r:River) =
match r with
|R(Name,_,_) when Name = n -> true
|R(_,_,Tr) -> contains n Tr
|_ -> false
However F# cant recoginze Tr as Tr is a list and not of type river so i can't pass it in of course, how can i do this in a nice and clean way without declaring two seperate functions to help?
Gus's answer fixes the specific issue and answers the question, but often things like this are slightly more elegant if work on a list of rivers (a 'forest' of trees) rather than a single one.
The solution is a little odd because the recursive step creates a new river to search in based on the tail of the tributaries of the input river, perfectly valid, but if feels a little odd.
first lets tidy up the types
type Name = string
type Flow = int
type Tributaries = River list
and River = R of Name * Flow * Tributaries
now we write something that feels harder than what you want to do, but is in fact (to me) intuitively easier to understand, i.e. you check the tail of the passed list AND you check the tributaries into the current river.
let rec containsTributaries (n: Name) (rs: River list) =
match rs with
| R (name, _, _) :: _ when name = n -> true
| R (_, _, tribs) :: tail -> containsTributaries n tail || containsTributaries n tribs
| _ -> false
then searching for a single river is trivial
let rec contains (n: Name) (river: River) =
containsTributaries n [ river ]
(but basically this is the same answer as Gus's)
The problem is Tr is a list and your function expect a River structure.
So, you would have to decompose the list in head and tail and check on both.
You can do that by changing the second match:
|R(_,_,Tr) -> contains n Tr
to
| R (name, f, x::xs) -> contains n x || contains n (R (name, f, xs))
Of course there are more efficient ways of doing this and you can use built in functions, but if you're learning this is the solution you want to come up in first place.
Hi I'm new to f# and I got this exercise I can't figure out:
"Implement a Function :"
let compress (l : List<'a>) : List<'a> = ...
That removes consecutive occurences of the same element in l. for example compressing [a;a;a;a;b;b;c] to [a;b;c]
I'm not allowed to use the built-in functions of f# and need to do this with pattern matching.
My current code (it's not much) :
let rec compress (l: List<'a>) : List<'a> =
match l with
| [] -> l
thanks for the help!
For any recursive function you need to consider: 1. the terminal case and 2. the general case. In your scenario:
the empty list []
non-empty list x::xs (where x represents the head of the list and xs the rest aka tail)
The other important aspect to consider when you build such a functions is to assume it works for a previous value. For example in the case of factorial, we assume the function already works for a previous scenario e.g. factorial of n-1.
let fact n =
match n with
| 0 | 1 -> 1
| _ -> n * fact (n-1)
First, I defined type for finding max value.
type my_val = NUM of int
| PLUS of my_val * val
| MULT of my_val * val
| MAX of my_val list
Therefore, MAX [NUM 9, NUM 20, NUM 3] should be 20. That's what I wanted to do...
I should make a function which computes the result of val's computation...
Here's what I wrote.
let rec eval: my_val -> int = fun given ->
match given with
| NUM i -> i
| PLUS (i, j) -> eval(i) + eval(j)
| MULT (i, j) -> eval(i) * eval(j)
| MAX i ->
(match i with
| [] -> 0
| my_hd::[] -> eval(my_hd)
| my_hd::my_tl -> if eval(my_hd) < eval(my_tl.hd) then eval(my_tl)
else eval(my_hd::my_tl.tl))
The problem occurs in my_hd < my_tl.hd line.
It gives me this error.
Unbound recored field hd
I guess that's because I tried to compare values of my_tl.hd, whose type is my_val?
But I couldn't think of the other way to solve this issue..
In OCaml, . when applied to a variable name means record access. my_tl.hd means you're trying to access the record field hd of the record my_tl. The compiler tells you that this won't work because there is no record field called hd in scope. my_tl also isn't a record of course, but the compiler hasn't gotten that far yet.
What you seem to want to use instead is the List.hd function, and later the List.tl function. I would however recommend against using these as they're unsafe. If given an empty list they will blow up.
Instead you might want to use a pattern to extract the first two elements from the list:
| my_hd1::my_hd2::my_tl ->
if eval(my_hd1) < eval(my_hd2) then
eval(my_hd2 :: my_tl)
else
eval(i)
This will never fail, and if you forget to cover the case of just one element the compiler will tell you.
Finally, using i and j as variable names for values that are not counters will get you lots of weird looks. a and b, or x and y are more commonly used as a short-hand if you have several "primary" values of the same type, but in this case you should really use more descriptive names.
Edit: Also, you should still not use parentheses for function application. That's just going to confuse you further when at some point you add another argument like you're used to, and get weird type errors.
I have the two datatypes:
datatype 'a Tree = LEAF of 'a | NODE of ('a Tree) * ('a Tree)
and
datatype 'a myTree = myLEAF of 'a | myNODE of 'a * 'a * 'a myTree * 'a myTree
With these two, I need to be able to find the min and max values of a tree.
For example:
findMin (NODE(NODE(LEAF(5),NODE(LEAF(6),LEAF(8))),LEAF(4)))
will produce 4.
I have been working on this for some time now, and I'm quite confused.
Any guidance would be helpful. Thank you.
You know that there is at least one element in every 'a Tree, so there is always a min/max.
Use pattern matching on each of the two constructors LEAF and NODE, and use recursion in the NODE case, since the two branches might have different min/max values and the min/max for the node is determined by whatever is min/max for its branches. And use the built-in helper functions Int.min and Int.max, if you're finding the min/max integers of a tree. (Your example suggests that this is the case.)
fun findMin (LEAF x) = (* ... *)
| findMin (NODE (leftTree, rightTree)) =
let (* ... use findMin recursively on each branch ... *)
in (* ... find the minimal value of the two branches ... *)
end
I'm not sure what the 'a myTree type is good for: It is a binary tree in that it has two 'a myTree branches per node, but it also has two 'a elements per node? Should you be interested in finding the min/max of either of those values? Or is one a key and another a value in some tree-based dictionary structure? If so, then why is it 'a -> 'a and not 'a -> 'b? It is hard to solve a problem when you don't understand the problem statement, and the datatype is a large portion of that.
Edit: Since you've provided a solution yourself, let me give some feedback on it:
fun findMin (LEAF(v)) = v
| findMin (NODE(left, right)) =
if findMin(left) < findMin(right)
then findMin(left)
else findMin(right)
This solution is very inefficient since it calls itself three times for each node's entire subtree. That means the number of function calls roughly follows the recurrence relation f(0) = 1 and f(n) = 3 ⋅ f(n-1). This is equivalent to 3n or exponentially many calls to find the minimal element in a list of n elements.
Here is a way that take linear time by temporarily storing the result you use twice:
fun findMin (LEAF v) = v
| findMin (NODE (left, right)) =
let val minLeft = findMin left
val minRight = findMin right
in if minLeft < minRight then minLeft else minRight
end
There is no reason to perform the Herculean task of calculating findMin left and findMin right more than once in every node of the tree. Since we refer to it multiple time, a let-in-end is an easy way to bind the results to lexically scoped names, minLeft and minRight.
The expression if minLeft < minRight then minLeft else minRight actually has a name in the standard library: Int.min. So we could do:
fun findMin (LEAF v) = v
| findMin (NODE (left, right)) =
let val minLeft = findMin left
val minRight = findMin right
in Int.min (minLeft, minRight)
end
But the reason for using a let-in-end has actually evaporated, since, with the help of a library function, we're now only referring to findMin left (aka minLeft) and findMin right (aka minRight) once now. (Actually, we are referring to them more than once, but that is inside Int.min in which the result has also been bound to a temporary, lexically scoped name.)
So we ditch the let-in-end for a much shorter:
fun findMin (LEAF v) = v
| findMin (NODE (left, right)) = Int.min (findMin left, findMin right)
In any case, these are all equally optimal: They use only n recursive function calls for n elements in the tree, which is the least you can do when the elements aren't sorted. Now, if you knew the smaller elements were always to the left, you'd have a binary search tree and you could find the min/max much faster. :-)
Edit (again): Just for fun, you could find the min/max simultaneously:
fun findMinMax (LEAF v) = (v, v)
| findMinMax (NODE (left, right)) =
let val (minLeft, maxLeft) = findMinMax left
val (minRight, maxRight) = findMinMax right
in (Int.min (minLeft, minRight), Int.max(maxLeft, maxRight))
end
I think one problem is that you're thinking hard about how to traverse the tree and check all the nodes in some order and keep track of things, but recursion will handle that for you.
Your tree has two cases; it is either a leaf, or a node with two subtrees.
This suggests that the solution will also have two cases: one for leaves and one for internal nodes.
Write down (in your own words, not code) how you would find the minimum in
a leaf; and
an internal node if you already knew the respective minimums of its subtrees -- don't worry about how to find them yet, but pretend that you know what they are.
Then write down how you find the minimums of the subtrees of an internal node.
(This is a recursion, so you've already solved this problem, before you started thinking about it.)
Then you translate it into ML.
I was 100% just overthinking the problem too much. Thank you both for your help! I got my answer.
fun findMin (LEAF(v)) = v
| findMin (NODE(left, right)) =
if findMin(left) < findMin(right)
then findMin(left)
else findMin(right)
fun findMax (LEAF(v)) = v
| findMax (NODE(left, right)) =
if findMax(left) > findMax(right)
then findMax(left)
else findMax(right)
I have to define a list in which:
1 is a member
if n is a member, so are 2n+1 and 3n+1
So the list is infinite and must be sorted. When loaded to GHCi, the command:
"take 10 theList"
will produce:
[1,3,4,7,9,10,13,15,19,21]
Below are my codes:
theList = ([1] ++ concat [[(x*2+1),(x*3+1)]|x<-theList])
It seems to work except for that it is not sorted, the same command as above produces:
[1,3,4,7,10,9,13,15,22,21]
Does anyone have any idea to sort that out?
Thanks
The problem can be though of as a infinite binary tree (A and B are labels for the branches):
1__ B
| 4___
| \ 13 ...
A 3_ \
| \ 9 ...
7 10
...
Thinking about it this way, we can see that we want to write a function ("listify") that converts the "tree" into a sorted list. This is where Haskell is really nice: if we have a function (merge) that takes two (infinite) sorted lists and merges them into one sorted list (you should write this function), then listify-ing the tree is simply listify-ing the two branches, merging them and putting the root at the start, i.e. in the tree above
1:merge (listify A) (listify B)
Since this is homework I won't say much more, but any branch of the tree is entirely determined by the root node, so the type signature of listify can be Integer -> [Integer]. And once you have listify, then theList = listify 1.
Another way of seeing this is as a filtered list of integers. The number n is part of the sequence if n = 1 (mod 2) and (n-1)/2 is a part of the sequence, or if n = 1 (mod 3) and (n-1)/3 is a part of the sequence.