I have a method for a class that implements a set for integers using the binary search tree data structure. One of the methods is a contains method that returns true if a set contains a given integer
Both implementation of the method below is correct, but I'm trying to understand why doing it this way:
def contains(x: Int): Boolean =
if (x < elem) left.contains(x)
else if (elem < x) right.contains(x)
else true
is sufficient compared to being exhaustive and doing it this way:
def contains(x: Int): Boolean =
if (x < elem) left.contains(x)
else if (elem < x) right.contains(x)
else if (elem == x) true
else false
What is the intuitive reason for the method in the first approach returning false if the integer does not belong in the set?
You are right to be suspicious because it appears that the only way to end recursion is by returning true.
However I think you will find that the tree has different classes for node elements and leaf elements. What you have shown is the contains method for a node. The contains method for a leaf will just returns false, ending the recursion.
Alternatively, it may be the left and right are Option[Node]. In this case you will get false if the Option is None because None.contains(_) is always false.
A binary search tree is always constructed such that left branch has elements that are smaller than the node value - elem, and right branch elems are all larger than elem.
Following this logic if your x is neither smaller, nor larger than elem you are left with only possibility: it's equal to the elem. Hence, no need to test for equality, and the second implementation's: else false will always be a dead branch.
Think about it this way: if you take two numbers and neither of them is smaller or bigger than the other, then they must be the same number.
How can I write an algorithm that determines if a function f from the finite set A to the finite set B is an onto function.
This is what I have so far:
A: array ( members of set A )
B: array ( members of set B )
Mapped: associative array of Boolean variables.
for each b in B:
Mapped[b] = false
for each a in A:
Mapped[f(a)] = true
Onto = true;
for each b in B:
Onto = Onto AND Mapped[b]
return Onto
Is this correct?
Yeah, that'll work. A potentially easier approach would be
for each a in A:
remove f(a) from B
return (is B empty?)
And then of course you should sort B first, so you can remove more quickly.
Let y be a set or list of numbers, e.g List(1,2,3,4) and suppose val x=1 so i need to check whether x is present in y collection. In this case boolean result as true is expected, and suppose val x=7 where the result should be false.
Just use contains to check whether value exists or not.
list.contains(value)
For sets consider
val s = Set(1,2,3,4)
s(1)
Boolean = true
a short for set inclusion, implemented by
s.apply(1)
Boolean = true
Moreover,
s(7)
Boolean = false
Valid for lists and sets alike (in addition to contains) is exists, for example,
s.exists(_ == 1)
Boolean = true
s.exists(_ == 7)
Boolean = false
I tried Google search and could not find a decent forall example. What does it do? Why does it take a boolean function?
Please point me to a reference (except the Scaladoc).
The forall method takes a function p that returns a Boolean. The semantics of forall says: return true if for every x in the collection, p(x) is true.
So:
List(1,2,3).forall(x => x < 3)
means: true if 1, 2, and 3 are less than 3, false otherwise. In this case, it will evaluate to false since it is not the case all elements are less than 3: 3 is not less than 3.
There is a similar method exists that returns true if there is at least one element x in the collection such that p(x) is true.
So:
List(1,2,3).exists(x => x < 3)
means: true if at least one of 1, 2, and 3 is less than 3, false otherwise. In this case, it will evaluate to true since it is the case some element is less than 3: e.g. 1 is less than 3.
A quick example of how you can play with this function using a Scala script.
create a myScript.scala file with
println(args.forall(p => (p.equals("a"))))
and call it with
scala myScript.scala a a a // true
scala myScript.scala a b c // false
Scala's forall is also a great tool to do something like applying logical and to a list of boolean values with the early exist:
val evalResults: List[Boolean] = List(evaluateFunc1(), evaluateFunc2(), evaluateFunc3(), evaluateFunc4(), evaluateFunc5())
evalResults.forall(result => result == true)
In Stanford Scala course I've come across the following assignment:
Exercise 1 – Sets as Functions:
In this exercise we will represent sets as functions from Ints to Booleans:
type Set = Int => Boolean
a) Write a function "set" that takes an Int parameter and returns a Set containing that Int.
b) Write a function "contains" that takes a Set and an Int as parameters and returns true if the Int is in the Set and false otherwise.
c) Write the functions "union", "intersect", and "minus" that take two Sets as parameters and return a Set.
d) Can you write a function "subset" which takes two Sets as parameters and returns true if the first is a subset of the second and false otherwise?
Solutions to the a, b and c are fairly trivial:
def set(i: Int): Set = n => n == i
def contains(s: Set, i: Int) = s(i)
def union(a: Set, b: Set): Set = i => a(i) || b(i)
def intersect(a: Set, b: Set): Set = i => a(i) && b(i)
def minus(a: Set, b: Set): Set = i => a(i) && !b(i)
But is there any elegant solution for d?
Of course, strictly speaking, the answer to d is "yes", as I can write something like:
def subset(a: Set, b: Set) = Int.MinValue to Int.MaxValue filter(a) forall(b)
but that's probably not the right way.
I don't think it's possible without iterating through all the integers. For a pseudo-proof, look at the desired type:
def subset: (a: Set, b: Set): Boolean
Somehow, we've got to produce a Boolean when all we have to work with are sets (a, b) of type Int => Boolean, and integer equality (Int, Int) => Boolean. From these primitives, the only way to get a Boolean value is to start with Int values. Since we don't have any specific Int's in our hands, the only option is to iterate through all of them.
If we had a magical oracle, isEmpty: Set => Boolean, the story would be different.
A final option is to encode "false" as the empty set and "true" as anything else, thus changing the desired type to:
def subset: (a: Set, b: Set): Set
With this encoding, logical "or" corresponds to the set union operation, but I don't know that logical "and" or "not" can be defined easily.
We have
Set A =
Returns the intersection of the two given sets,
the set of all elements that are both in `s` and `t`.
Set B =
Returns the subset of `s` for which `p` holds.
Isn't Set A is equivalent to Set B
def filter(s: Set, p: Int => Boolean): Set = intersect(s, p)
I agree with Kipton Barros, you would have to check all values for Ints since you want to prove that forall x, a(x) implies b(x).
Regarding the optimization of it, I'd probably write:
def subset(a: Set, b: Set) = Int.MinValue to Int.MaxValue exists(i => !a(i) || b(i))
since !a(i) || b(i) is equivalent to a(i) implies b(i)
Later on in the Coursera exercises bounded sets are introduced and then forall() and exists() as universal and existential quantifiers over the bounds. subset() was not in the exercises but is similar to forall. Here is my version of subset():
// subset(s,p) tests if p is a subset of p returning true or false
def subset(s: Set, p: Set): Boolean = {
def iter(a: Int): Boolean = {
if (a > bound) { true
} else if (contains(p, a)) {
if (contains(s, a)) iter(a + 1) else false
} else iter(a+1)
}
iter(-bound)
}
Here is another version of it using contains function:
def union(s: Set, t: Set): Set = x => contains(s,x) || contains(t,x)
def intersect(s: Set, t: Set): Set = x => contains(s,x) && contains(t,x)
def diff(s: Set, t: Set): Set = x => contains(s,x) && !contains(t,x)
def filter(s: Set, p: Int => Boolean): Set = x => contains(s, x) && p(x)
If there are two sets A and B, then A intersect B is a subset of A and B. Mathematically proven: A ∩ B ⊆ A and A ∩ B ⊆ B. Function can be written like this:
def filter(s: Set, p: Int => Boolean): Set = x => s(x) && p(x)
Or
def intersect(s: Set, t: Set): Set = x => s(x) && t(x)
def filter(s: Set, p: Int => Boolean): Set = intersect(s,p)