Last active
August 29, 2015 13:57
-
-
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 :)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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