Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision | |||
fp:homework01 [2023/03/21 20:14] pdmatei |
fp:homework01 [2023/03/22 08:44] (current) pdmatei |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== H01. Functional Sets ====== | + | ====== Homework 1. Sets as functions ====== |
===== Problem statement ===== | ===== Problem statement ===== | ||
Line 9: | Line 9: | ||
In our implementation, $math[U] will be the set of integers, hence we shall encode only **sets of integers**. Hence, the type of a set will be: | In our implementation, $math[U] will be the set of integers, hence we shall encode only **sets of integers**. Hence, the type of a set will be: | ||
<code scala> | <code scala> | ||
- | type Set = Int => Boolean | + | Int => Boolean |
</code> | </code> | ||
Line 29: | Line 29: | ||
**1.** Write a function ''singleton'' which takes an integer and returns **the set** containing only that integer: | **1.** Write a function ''singleton'' which takes an integer and returns **the set** containing only that integer: | ||
<code scala> | <code scala> | ||
- | def singleton(x: Int): Set = ??? | + | def singleton(x: Int): Int => Boolean = ??? |
</code> | </code> | ||
Line 37: | Line 37: | ||
**2.** Write a function ''member'' which takes a set and an integer and checks if the integer is a member of the set. Note that ''member'' should be defined and called as a curry function: | **2.** Write a function ''member'' which takes a set and an integer and checks if the integer is a member of the set. Note that ''member'' should be defined and called as a curry function: | ||
<code scala> | <code scala> | ||
- | def member(e: Int)(set: Set): Boolean = ??? | + | def member(set: Int => Boolean)(e: Int): Boolean = ??? |
</code> | </code> | ||
Line 43: | Line 43: | ||
<code scala> | <code scala> | ||
- | def fromBounds(start: Int, stop: Int): Set = ??? | + | def fromBounds(start: Int, stop: Int): Int => Boolean = ??? |
</code> | </code> | ||
- | **5.** Write the function which performs the union of two sets: | + | **4.** Write a function which performs the intersection of two sets: |
<code scala> | <code scala> | ||
- | def union(set1: Set, set2: Set): Set = ??? | + | def intersection(set1: Int => Boolean, set2: Int => Boolean): Int => Boolean = ??? |
</code> | </code> | ||
- | **6.** Write a function which computes the complement of a set with respect to the set of integers: | + | **5.** Write the function which performs the union of two sets: |
<code scala> | <code scala> | ||
- | def complement(s1: Set): Set = ??? | + | def union(set1: Int => Boolean, set2: Int => Boolean): Int => Boolean = ??? |
</code> | </code> | ||
- | **6.** Write a function which computes the sum of value ''b'' to all elements from a set, for given **bounds**. Use a tail-end recursive function: | + | **6.** Write a function which computes the sum of all elements from a set, for given **bounds**. Use a tail-end recursive function: |
<code scala> | <code scala> | ||
- | def sumSet(b: Int)(start: Int, stop: Int)(set: Set): Int = { | + | def sumSet(start: Int, stop: Int, set: Int => Boolean): Int = { |
def auxSum(crt: Int, acc: Int): Int = ??? | def auxSum(crt: Int, acc: Int): Int = ??? | ||
??? | ??? | ||
Line 64: | Line 64: | ||
</code> | </code> | ||
- | **7.** Generalise the previous function such that we can **fold** a set using any binary commutative operation over integers. Make sure this is a **left** fold: Folding the set: ''{x,y,z}'' with ''b'' should produce: ''( (b op x) op y) op z'' | + | **7.** Generalise the previous function such that we can **fold** a set using any binary commutative operation over integers: |
<code scala> | <code scala> | ||
- | def foldLeftSet | + | def foldSet( |
- | (b:Int) // initial value | + | start: Int, // bounds (inclusive) |
- | (op: (Int,Int) => Int) // folding operation | + | stop: Int, |
- | (start: Int, stop: Int) // bounds (inclusive) | + | op: (Int, Int) => Int, // folding operation |
- | (set: Set): Int = ??? // the set to be folded | + | initial: Int, // initial value |
- | </code> | + | set: Int => Boolean // the set to be folded |
- | + | ): Int = ??? | |
- | **7.** Implement an alternative to the previous function, namely **foldRight**. Applying ''foldRight'' on the set ''{x,y,z}'' with ''b'' should produce: ''a op (b op (c op b))''. Use direct recursion instead of tail recursion. | + | |
- | <code scala> | + | |
- | def foldRightSet | + | |
- | (b:Int) // initial value | + | |
- | (op: (Int,Int) => Int) // folding operation | + | |
- | (start: Int, stop: Int) // bounds (inclusive) | + | |
- | (set: Set): Int = ??? // the set to be folded | + | |
- | </code> | + | |
- | + | ||
- | **X.** Implement operation ''filter'' which takes a set and returns another one containing only those elements that satisfy the predicate: | + | |
- | <code scala> | + | |
- | def filter(p: Int => Boolean)(set: Set): Set = ??? | + | |
- | </code> | + | |
- | + | ||
- | **X.** Implement a function which **partitions** a set into two sets. The left-most contains those elements that satisfy the predicate, while the right-most contains those elements that do not satisfy the predicate. Use pairs. A pair is constructed with simple parentheses: ''(1,2)''. Suppose ''val p: (Int,Int)'' is a pair of two integers. Then ''p._1'' is the left-most part of the pair while ''p._2'' is the right-most part of the pair. | + | |
- | <code scala> | + | |
- | def partition(p: Int => Boolean)(set: Set): (Set,Set) = ??? | + | |
</code> | </code> | ||
**8.** Implement a function ''forall'' which checks if all elements in a given range of a set satisfy a predicate (condition). (Such a condition may be that all elements from given bounds are even numbers). | **8.** Implement a function ''forall'' which checks if all elements in a given range of a set satisfy a predicate (condition). (Such a condition may be that all elements from given bounds are even numbers). | ||
<code scala> | <code scala> | ||
- | def forall(cond: Int => Boolean) // condition to be checked | + | def forall( |
- | (start: Int, stop: Int) // start,stop values (inclusive) | + | start: Int, // start value (inclusive) |
- | (set: Set): Boolean // set to be checked | + | stop: Int, // stop value (inclusive) |
- | = ??? | + | condition: Int => Boolean, // condition to be checked |
+ | set: Int => Boolean // set to be checked | ||
+ | ): Boolean = ??? | ||
</code> | </code> | ||
**9.** Implement a function ''exists'' which checks if a predicate holds for **some** element from the range of a set. Hint: it is easier to implement ''exists'' using the logical relation: $math[ \exists x. P(X) \iff \lnot \forall x.\lnot P(X)]. | **9.** Implement a function ''exists'' which checks if a predicate holds for **some** element from the range of a set. Hint: it is easier to implement ''exists'' using the logical relation: $math[ \exists x. P(X) \iff \lnot \forall x.\lnot P(X)]. | ||
- | |||
- | **X.** Implement the function ''setOfDivByK'' which returns the set of integers divisible by a value ''k''. Use the appropriate functions you have defined. | ||
- | <code scala> | ||
- | def setOfDivByK(k: Int): Set = ?? | ||
- | </code> | ||
- | |||
- | **X.** Implement the function ''moreDivs'' which verifies if ''set1'' contains more divisors of ''k'' than ''set2'', over the range ''[start,stop]''. Use any combination of the previous functions you have defined for your implementation. | ||
<code scala> | <code scala> | ||
- | def moreDivs(k: Int)(start: Int, stop:Int)(set1: Set, set2: Set): Boolean = ??? | + | /* implement a function exists, using forall */ |
+ | def exists( | ||
+ | start: Int, // start value (inclusive) | ||
+ | stop: Int, // stop value (inclusive) | ||
+ | condition: Int => Boolean, // condition to be checked | ||
+ | set: Int => Boolean // set | ||
+ | ): Boolean = ??? | ||
</code> | </code> | ||