Skip to content

Instantly share code, notes, and snippets.

@johnelf
Last active August 29, 2015 13:57
Show Gist options
  • Save johnelf/9658893 to your computer and use it in GitHub Desktop.
Save johnelf/9658893 to your computer and use it in GitHub Desktop.
The following exercises have come from of a course that I give on Functional Programming. I have assigned them difficulty ratings to make it a bit more exciting. Download the compilable source code from here or find it below. Enjoy :)
// You are not permitted to use these List methods:
// * length
// * map
// * filter
// * ::: (and variations such as ++)
// * flatten
// * flatMap
// * reverse (and variations i.e. reverseMap, reverse_:::)
// This also means you are not permitted to use for-comprehensions on Lists.
// You are permitted to use the functions you write yourself. For example, Exercise 2 may use Exercise 1 or Exercise 3.
// Using permitted existing methods where appropriate will attract marks for elegance.
import org.omg.CosNaming.NamingContextPackage.NotFound
object test {
def succ(n: Int) = n + 1 //> succ: (n: Int)Int
def pred(n: Int) = n - 1 //> pred: (n: Int)Int
// Exercise 1
// Relative Difficulty: 1
// Correctness: 2.0 marks
// Performance: 0.5 mark
// Elegance: 0.5 marks
// Total: 3
def add(x: Int, y: Int): Int = {
if (y > 0) add(succ(x), pred(y))
else x
} //> add: (x: Int, y: Int)Int
// Exercise 2
// Relative Difficulty: 2
// Correctness: 2.5 marks
// Performance: 1 mark
// Elegance: 0.5 marks
// Total: 4
def sum(x: List[Int]): Int = x match {
case Nil => 0
case head :: tail => add(head, sum(tail))
} //> sum: (x: List[Int])Int
// Exercise 3
// Relative Difficulty: 2
// Correctness: 2.5 marks
// Performance: 1 mark
// Elegance: 0.5 marks
// Total: 4
def length[A](x: List[A]): Int = x match {
case Nil => 0
case head :: tail => add(1, length(tail))
} //> length: [A](x: List[A])Int
// Exercise 4
// Relative Difficulty: 5
// Correctness: 4.5 marks
// Performance: 1.0 mark
// Elegance: 1.5 marks
// Total: 7
def map[A, B](x: List[A], f: A => B): List[B] = x match {
case Nil => Nil
case head :: tail => f(head) :: map(tail, f)
} //> map: [A, B](x: List[A], f: A => B)List[B]
// Exercise 5
// Relative Difficulty: 5
// Correctness: 4.5 marks
// Performance: 1.5 marks
// Elegance: 1 mark
// Total: 7
def filter[A](x: List[A], f: A => Boolean): List[A] = x match {
case Nil => Nil
case head :: tail => {
if (f(head)) {
head :: filter(tail, f)
} else {
filter(tail, f)
}
}
} //> filter: [A](x: List[A], f: A => Boolean)List[A]
// Exercise 6
// Relative Difficulty: 5
// Correctness: 4.5 marks
// Performance: 1.5 marks
// Elegance: 1 mark
// Total: 7
def append[A](x: List[A], y: List[A]): List[A] = y match {
case Nil => x
case head :: tail => x match {
case Nil => y
case head :: tail => head :: append(tail, y)
}
} //> append: [A](x: List[A], y: List[A])List[A]
// Exercise 7
// Relative Difficulty: 5
// Correctness: 4.5 marks
// Performance: 1.5 marks
// Elegance: 1 mark
// Total: 7
def concat[A](x: List[List[A]]): List[A] = x match {
case Nil => Nil
case head :: tail => append(head, concat(tail))
} //> concat: [A](x: List[List[A]])List[A]
// Exercise 8
// Relative Difficulty: 7
// Correctness: 5.0 marks
// Performance: 1.5 marks
// Elegance: 1.5 mark
// Total: 8
def concatMap[A, B](x: List[A], f: A => List[B]): List[B] = x match {
case Nil => Nil
case head :: tail => append(f(head), concatMap(tail, f))
} //> concatMap: [A, B](x: List[A], f: A => List[B])List[B]
// Exercise 9
// Relative Difficulty: 8
// Correctness: 3.5 marks
// Performance: 3.0 marks
// Elegance: 2.5 marks
// Total: 9
def maximum(x: List[Int]): Int = x match {
case Nil => throw new RuntimeException("Empty List")
case head :: Nil => head
case list => {
if (list.head > maximum(list.tail)) list.head
else maximum(list.tail)
}
} //> maximum: (x: List[Int])Int
// Exercise 10
// Relative Difficulty: 10
// Correctness: 5.0 marks
// Performance: 2.5 marks
// Elegance: 2.5 marks
// Total: 10
def reverse[A](x: List[A]): List[A] = x match {
case Nil => Nil
case head :: tail => append(reverse(tail), List(head))
} //> reverse: [A](x: List[A])List[A]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment