| 449 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      1 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      2 | // Task 1 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      3 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      4 | abstract class Tree
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      5 | case class Leaf(x: Int) extends Tree
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      6 | case class Node(left: Tree, right: Tree) extends Tree 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      7 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      8 | def mirror(t: Tree) : Tree = t match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      9 |   case Leaf(n) => Leaf(n)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     10 |   case Node(l, r) => Node(mirror(r), mirror(l))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     11 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     12 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     13 | def sum_tree(t: Tree) : Int = t match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     14 |   case Leaf(n) => n
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     15 |   case Node(l, r) => sum_tree(l) + sum_tree(r)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     16 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     17 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     18 | // Task 2
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     19 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     20 | // version with default argument
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     21 | def remdups(xs: List[Int], acc: Set[Int] = Set()) : List[Int] = xs match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     22 |   case Nil => Nil
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     23 |   case x::xs => if (acc.contains(x)) remdups(xs, acc + x)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     24 |                 else x::remdups(xs, acc + x)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     25 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     26 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     27 | //version with auxiliary function
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     28 | def remdups(xs: List[Int]) = {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     29 |   def aux(xs: List[Int], acc: Set[Int]) : List[Int] = xs match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     30 |     case Nil => Nil
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     31 |     case x::xs => if (acc.contains(x)) aux(xs, acc + x)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     32 |                   else x::aux(xs, acc + x)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     33 |   }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     34 |   aux(xs, Set())
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     35 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     36 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     37 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     38 | // Task 3
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     39 | def indexOfOption(xs: List[Int], e: Int) : Option[Int] = xs match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     40 |   case Nil => None
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     41 |   case x::xs => if (x == e) Some(0)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     42 |                 else indexOfOption(xs, e).map(_ + 1)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     43 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     44 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     45 | indexOfOption(List(1,2,3,4,5,6), 7) // => None
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     46 | indexOfOption(List(1,2,3,4,5,6), 4) // => Some(3)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     47 | indexOfOption(List(1,2,3,4,3,6), 3) // => Some(2)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     48 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     49 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     50 | // Task 4 (Pattern Matching, If-Guards, hard)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     51 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     52 | def height(t: Tree) : Int = t match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     53 |   case Leaf(_) => 0
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     54 |   case Node(l, r) => 1 + List(height(l), height(r)).max
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     55 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     56 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     57 | def balance(t: Tree) : Tree = t match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     58 |   case Leaf(n) => Leaf(n)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     59 |   case Node(l, r) if (height(l) - height(r)).abs <= 1 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     60 |     => Node(l, r)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     61 |   case Node(l, r : Node) if height(l) < height(r) => 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     62 |     balance(Node(Node(l, r.left), r.right))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     63 |   case Node(l : Node, r) if height(l) > height(r) => 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     64 |     balance(Node(l.left, Node(l.right, r)))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     65 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     66 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     67 | balance(Node(Leaf(1), Node(Leaf(2), Node(Leaf(3), Leaf(4)))))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     68 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     69 | // Task 5 (fold, hard)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     70 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     71 | def fold(xs: List[Int], f: (Int, Int) => Int, u: Int) : Int = xs match {
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     72 |   case Nil => u
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     73 |   case x::xs => f(x, fold(xs, f, u))
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     74 | }
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     75 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     76 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     77 | def sum(xs: List[Int]) = fold(xs, _ + _, 0)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     78 | def prod(xs: List[Int]) = fold(xs, _ * _, 1) |