progs/lecture3.scala
author Christian Urban <urbanc@in.tum.de>
Tue, 21 Nov 2017 16:31:11 +0000
changeset 152 114a89518aea
parent 77 3cbe3d90b77f
child 153 4383809c176a
permissions -rw-r--r--
updated
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
     1
// Scala Lecture 3
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
     2
//=================
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
     3
152
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
     4
// adding two binary strings very, very lazy manner
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
     5
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
     6
def badd(s1: String, s2: String) : String = 
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
     7
  (BigInt(s1, 2) + BigInt(s2, 2)).toString(2)
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
     8
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
     9
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    10
// collatz function on binary numbers
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    11
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    12
def bcollatz(s: String) : Long = (s.dropRight(1), s.last) match {
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    13
  case ("", '1') => 1                                  // we reached 1
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    14
  case (rest, '0') => 1 + bcollatz(rest)               // even number => divide by two
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    15
  case (rest, '1') => 1 + bcollatz(badd(s + '1', s))   // odd number => s + '1' is 2 * s + 1
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    16
                                                       //               add another s gives 3 * s + 1  
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    17
} 
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    18
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    19
bcollatz(9.toBinaryString)
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    20
bcollatz(837799.toBinaryString)
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    21
bcollatz(100000000000000000L.toBinaryString)
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    22
bcollatz(BigInt("1000000000000000000000000000000000000000000000000000000000000000000000000000").toString(2))
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    23
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    24
def conv(c: Char) : Int = c match {
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    25
  case '0' => 0
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    26
  case '1' => 1
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    27
}
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    28
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    29
def badds(s1: String, s2: String, carry: Int) : String = (s1, s2, carry) match {
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    30
  case ("", "", 1) => "1"
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    31
  case ("", "", 0) => ""
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    32
  case (cs1, cs2, carry) => (conv(cs1.last) + conv(cs2.last) + carry) match {
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    33
    case 3 => badds(cs1.dropRight(1), cs2.dropRight(1), 1) + '1'
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    34
    case 2 => badds(cs1.dropRight(1), cs2.dropRight(1), 1) + '0'
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    35
    case 1 => badds(cs1.dropRight(1), cs2.dropRight(1), 0) + '1'
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    36
    case 0 => badds(cs1.dropRight(1), cs2.dropRight(1), 0) + '0'
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    37
  }
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    38
} 
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    39
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    40
def bcollatz2(s: String) : Long = (s.dropRight(1), s.last) match {
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    41
  case ("", '1') => 1                                          // we reached 1
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    42
  case (rest, '0') => 1 + bcollatz2(rest)                      // even number => divide by two
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    43
  case (rest, '1') => 1 + bcollatz2(badds(s + '1', '0' + s, 0))   // odd number => s + '1' is 2 * s + 1
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    44
                                                                  //         add another s gives 3 * s + 1  
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    45
} 
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    46
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    47
bcollatz2(9.toBinaryString)
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    48
bcollatz2(837799.toBinaryString)
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    49
bcollatz2(100000000000000000L.toBinaryString)
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    50
bcollatz2(BigInt("1000000000000000000000000000000000000000000000000000000000000000000000000000").toString(2))
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    51
114a89518aea updated
Christian Urban <urbanc@in.tum.de>
parents: 77
diff changeset
    52
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    53
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    54
// One of only two places where I conceded to mutable
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    55
// data structures: The following function generates 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    56
// new labels
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    57
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    58
var counter = -1
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    59
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    60
def fresh(x: String) = {
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    61
  counter += 1
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    62
  x ++ "_" ++ counter.toString()
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    63
}
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    64
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    65
fresh("x")
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    66
fresh("x")
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    68
// this can be avoided, but would have made my code more
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    69
// complicated
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    70
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    71
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    72
// Tail recursion
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    73
//================
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    74
71
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
    75
def my_contains(elem: Int, lst: List[Int]): Boolean = lst match {
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    76
  case Nil => false
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    77
  case x::xs => 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    78
    if (x == elem) true else my_contains(elem, xs)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    79
}
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    80
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    81
my_contains(4, List(1,2,3))
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    82
my_contains(2, List(1,2,3))
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    83
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    84
my_contains(1000000, (1 to 1000000).toList)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    85
my_contains(1000001, (1 to 1000000).toList)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    86
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    87
71
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
    88
//factorial V0.1
72
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
    89
import scala.annotation.tailrec
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
    90
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    91
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    92
def fact(n: Long): Long = 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    93
  if (n == 0) 1 else n * fact(n - 1)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    94
71
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
    95
fact(10000)                        // produces a stackoverflow
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    96
72
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
    97
@tailrec
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    98
def factT(n: BigInt, acc: BigInt): BigInt =
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
    99
  if (n == 0) acc else factT(n - 1, n * acc)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   100
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   101
72
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   102
println(factT(10000, 1))
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   103
71
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   104
// the functions my_contains and factT are tail-recursive 
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   105
// you can check this with 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   106
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   107
import scala.annotation.tailrec
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   108
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   109
// and the annotation @tailrec
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   110
71
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   111
// for tail-recursive functions the scala compiler
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   112
// generates loop-like code, which does not need
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   113
// to allocate stack-space in each recursive
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   114
// call; scala can do this only for tail-recursive
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   115
// functions
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   116
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   117
// consider the following "stupid" version of the
71
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   118
// coin exchange problem: given some coins and a
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   119
// total, what is the change can you get?
53
9f8751912560 updated
Christian Urban <urbanc@in.tum.de>
parents: 8
diff changeset
   120
71
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   121
val coins = List(4,5,6,8,10,13,19,20,21,24,38,39,40)
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   122
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   123
def first_positive[B](lst: List[Int], f: Int => Option[B]): Option[B] = lst match {
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   124
  case Nil => None
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   125
  case x::xs => 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   126
    if (x <= 0) first_positive(xs, f)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   127
    else {
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   128
      val fx = f(x)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   129
      if (fx.isDefined) fx else first_positive(xs, f)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   130
  }
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   131
}
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   132
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   133
72
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   134
import scala.annotation.tailrec
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   135
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   136
def search(total: Int, coins: List[Int], cs: List[Int]): Option[List[Int]] = {
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   137
  if (total < cs.sum) None 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   138
  else if (cs.sum == total) Some(cs) 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   139
  else first_positive(coins, (c: Int) => search(total, coins, c::cs))
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   140
}
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   141
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   142
search(11, coins, Nil)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   143
search(111, coins, Nil)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   144
search(111111, coins, Nil)
53
9f8751912560 updated
Christian Urban <urbanc@in.tum.de>
parents: 8
diff changeset
   145
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   146
val junk_coins = List(4,-2,5,6,8,0,10,13,19,20,-3,21,24,38,39, 40)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   147
search(11, junk_coins, Nil)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   148
search(111, junk_coins, Nil)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   149
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   150
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   151
import scala.annotation.tailrec
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   152
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   153
@tailrec
72
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   154
def searchT(total: Int, coins: List[Int], 
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   155
            acc_cs: List[List[Int]]): Option[List[Int]] = acc_cs match {
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   156
  case Nil => None
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   157
  case x::xs => 
71
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   158
    if (total < x.sum) searchT(total, coins, xs)
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   159
    else if (x.sum == total) Some(x) 
71
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   160
    else searchT(total, coins, coins.filter(_ > 0).map(_::x) ::: xs)
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   161
}
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   162
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   163
val start_acc = coins.filter(_ > 0).map(List(_))
71
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   164
searchT(11, junk_coins, start_acc)
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   165
searchT(111, junk_coins, start_acc)
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   166
searchT(111111, junk_coins, start_acc)
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   167
77
3cbe3d90b77f updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 73
diff changeset
   168
// Moral: Whenever a recursive function is resource-critical
3cbe3d90b77f updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 73
diff changeset
   169
// (i.e. works with large recursion depths), then you need to
3cbe3d90b77f updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 73
diff changeset
   170
// write it in tail-recursive fashion.
3cbe3d90b77f updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 73
diff changeset
   171
// 
3cbe3d90b77f updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 73
diff changeset
   172
// Unfortuantely, the Scala is because of current limitations in 
3cbe3d90b77f updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 73
diff changeset
   173
// the JVM not as clever as other functional languages. It can 
3cbe3d90b77f updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 73
diff changeset
   174
// only optimise "self-tail calls". This excludes the cases of 
3cbe3d90b77f updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 73
diff changeset
   175
// multiple functions making tail calls to each other. Well,
3cbe3d90b77f updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 73
diff changeset
   176
// nothing is perfect. 
3cbe3d90b77f updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 73
diff changeset
   177
3cbe3d90b77f updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 73
diff changeset
   178
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   179
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   180
71
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   181
// Polymorphic Types
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   182
//===================
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   183
72
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   184
// You do not want to write functions like contains, first 
71
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   185
// and so on for every type of lists.
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   186
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   187
72
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   188
def length_string_list(lst: List[String]): Int = lst match {
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   189
  case Nil => 0
72
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   190
  case x::xs => 1 + length_string_list(xs)
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   191
}
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   192
72
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   193
length_string_list(List("1", "2", "3", "4"))
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   194
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   195
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   196
def length[A](lst: List[A]): Int = lst match {
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   197
  case Nil => 0
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   198
  case x::xs => 1 + length(xs)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   199
}
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   200
53
9f8751912560 updated
Christian Urban <urbanc@in.tum.de>
parents: 8
diff changeset
   201
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   202
def map_int_list(lst: List[Int], f: Int => Int): List[Int] = lst match {
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   203
  case Nil => Nil
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   204
  case x::xs => f(x)::map_int_list(xs, f) 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   205
}
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   206
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   207
map_int_list(List(1, 2, 3, 4), square)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   208
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   209
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   210
// Remember?
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   211
def first[A, B](xs: List[A], f: A => Option[B]): Option[B] = ...
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   212
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   213
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   214
// polymorphic classes
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   215
//(trees with some content)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   216
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   217
abstract class Tree[+A]
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   218
case class Node[A](elem: A, left: Tree[A], right: Tree[A]) extends Tree[A]
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   219
case object Leaf extends Tree[Nothing]
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   220
72
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   221
val t0 = Node('4', Node('2', Leaf, Leaf), Node('7', Leaf, Leaf))
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   222
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   223
def insert[A](tr: Tree[A], n: A): Tree[A] = tr match {
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   224
  case Leaf => Node(n, Leaf, Leaf)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   225
  case Node(m, left, right) => 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   226
    if (n == m) Node(m, left, right) 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   227
    else if (n < m) Node(m, insert(left, n), right)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   228
    else Node(m, left, insert(right, n))
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   229
}
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   230
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   231
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   232
// the A-type needs to be ordered
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   233
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   234
abstract class Tree[+A <% Ordered[A]]
72
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   235
case class Node[A <% Ordered[A]](elem: A, left: Tree[A], 
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   236
                                 right: Tree[A]) extends Tree[A]
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   237
case object Leaf extends Tree[Nothing]
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   238
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   239
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   240
def insert[A <% Ordered[A]](tr: Tree[A], n: A): Tree[A] = tr match {
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   241
  case Leaf => Node(n, Leaf, Leaf)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   242
  case Node(m, left, right) => 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   243
    if (n == m) Node(m, left, right) 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   244
    else if (n < m) Node(m, insert(left, n), right)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   245
    else Node(m, left, insert(right, n))
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   246
}
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   247
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   248
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   249
val t1 = Node(4, Node(2, Leaf, Leaf), Node(7, Leaf, Leaf))
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   250
insert(t1, 3)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   251
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   252
val t2 = Node('b', Node('a', Leaf, Leaf), Node('f', Leaf, Leaf))
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   253
insert(t2, 'e')
53
9f8751912560 updated
Christian Urban <urbanc@in.tum.de>
parents: 8
diff changeset
   254
9f8751912560 updated
Christian Urban <urbanc@in.tum.de>
parents: 8
diff changeset
   255
9f8751912560 updated
Christian Urban <urbanc@in.tum.de>
parents: 8
diff changeset
   256
71
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   257
// Regular expressions - the power of DSLs in Scala
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   258
//==================================================
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   259
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   260
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   261
abstract class Rexp
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   262
case object ZERO extends Rexp
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   263
case object ONE extends Rexp
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   264
case class CHAR(c: Char) extends Rexp
71
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   265
case class ALT(r1: Rexp, r2: Rexp) extends Rexp     // alternative  r1 + r2
72
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   266
case class SEQ(r1: Rexp, r2: Rexp) extends Rexp     // sequence     r1 r2  
71
19dff7218b0d updated
Christian Urban <urbanc@in.tum.de>
parents: 68
diff changeset
   267
case class STAR(r: Rexp) extends Rexp               // star         r*
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   268
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   269
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   270
// (ab)*
72
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   271
val r0 = STAR(SEQ(CHAR('a'), CHAR('b')))
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   272
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   273
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   274
// some convenience for typing in regular expressions
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   275
import scala.language.implicitConversions    
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   276
import scala.language.reflectiveCalls 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   277
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   278
def charlist2rexp(s: List[Char]): Rexp = s match {
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   279
  case Nil => ONE
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   280
  case c::Nil => CHAR(c)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   281
  case c::s => SEQ(CHAR(c), charlist2rexp(s))
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   282
}
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   283
implicit def string2rexp(s: String): Rexp = charlist2rexp(s.toList)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   284
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   285
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   286
val r1 = STAR("ab")
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   287
val r2 = STAR("")
72
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   288
val r3 = STAR(ALT("ab", "baa baa black sheep"))
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   289
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   290
implicit def RexpOps (r: Rexp) = new {
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   291
  def | (s: Rexp) = ALT(r, s)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   292
  def % = STAR(r)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   293
  def ~ (s: Rexp) = SEQ(r, s)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   294
}
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   295
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   296
implicit def stringOps (s: String) = new {
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   297
  def | (r: Rexp) = ALT(s, r)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   298
  def | (r: String) = ALT(s, r)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   299
  def % = STAR(s)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   300
  def ~ (r: Rexp) = SEQ(s, r)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   301
  def ~ (r: String) = SEQ(s, r)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   302
}
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   303
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   304
val digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   305
val sign = "+" | "-" | ""
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   306
val number = sign ~ digit ~ digit.% 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   307
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   308
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   309
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   310
// Lazyness with style
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   311
//=====================
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   312
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   313
// The concept of lazy evaluation doesn’t really exist in 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   314
// non-functional languages, but it is pretty easy to grasp. 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   315
// Consider first 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   316
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   317
def square(x: Int) = x * x
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   318
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   319
square(42 + 8)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   320
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   321
// this is called strict evaluation
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   322
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   323
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   324
def expensiveOperation(n: BigInt): Boolean = expensiveOperation(n + 1) 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   325
val a = "foo"
72
9d8b172f5337 updated
Christian Urban <urbanc@in.tum.de>
parents: 71
diff changeset
   326
val b = "bar"
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   327
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   328
val test = if ((a == b) || expensiveOperation(0)) true else false
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   329
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   330
// this is called lazy evaluation
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   331
// you delay compuation until it is really 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   332
// needed; once calculated though, does not 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   333
// need to be re-calculated
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   334
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   335
// a useful example is
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   336
def time_needed[T](i: Int, code: => T) = {
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   337
  val start = System.nanoTime()
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   338
  for (j <- 1 to i) code
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   339
  val end = System.nanoTime()
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   340
  ((end - start) / i / 1.0e9) + " secs"
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   341
}
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   342
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   343
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   344
// streams (I do not care how many)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   345
// primes: 2, 3, 5, 7, 9, 11, 13 ....
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   346
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   347
def generatePrimes (s: Stream[Int]): Stream[Int] =
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   348
  s.head #:: generatePrimes(s.tail filter (_ % s.head != 0))
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   349
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   350
val primes: Stream[Int] = generatePrimes(Stream.from(2))
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   351
73
5e4696ebd8dc updated
Christian Urban <urbanc@in.tum.de>
parents: 72
diff changeset
   352
primes.take(10).toList
5e4696ebd8dc updated
Christian Urban <urbanc@in.tum.de>
parents: 72
diff changeset
   353
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   354
primes.filter(_ > 100).take(2000).toList
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   355
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   356
time_needed(1, primes.filter(_ > 100).take(2000).toList)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   357
time_needed(1, primes.filter(_ > 100).take(2000).toList)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   358
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   359
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   360
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   361
// streams are useful for implementing search problems ;o)
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   362
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   363
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   364
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   365
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   366
// The End
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   367
//=========
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   368
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   369
// A function should do one thing, and only one thing.
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   370
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   371
// Make your variables immutable, unless there's a good 
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   372
// reason not to.
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   373
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   374
// You can be productive on Day 1, but the language is deep.
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   375
68
8da9e0c16194 updated
Christian Urban <urbanc@in.tum.de>
parents: 67
diff changeset
   376
// I like best about Scala that it lets me write
67
ca5884c2e3bd updated
Christian Urban <urbanc@in.tum.de>
parents: 53
diff changeset
   377
// concise, readable code
68
8da9e0c16194 updated
Christian Urban <urbanc@in.tum.de>
parents: 67
diff changeset
   378