progs/lecture2.scala
changeset 319 b84ea52bfd8f
parent 318 029e2862bb4e
child 320 cdfb2ce30a3d
equal deleted inserted replaced
318:029e2862bb4e 319:b84ea52bfd8f
    73 
    73 
    74 
    74 
    75 // the same for files
    75 // the same for files
    76 Try(Some(Source.fromFile("text.txt").mkString)).getOrElse(None)
    76 Try(Some(Source.fromFile("text.txt").mkString)).getOrElse(None)
    77 
    77 
    78 // how to implement a function for reading something from files...
    78 
    79 
    79 // how to implement a function for reading 
       
    80 // (lines) something from files...
       
    81 //
    80 def get_contents(name: String) : List[String] = 
    82 def get_contents(name: String) : List[String] = 
    81   Source.fromFile(name).getLines.toList
    83   Source.fromFile(name).getLines.toList
    82 
    84 
       
    85 get_contents("text.txt")
    83 get_contents("test.txt")
    86 get_contents("test.txt")
    84 
    87 
    85 // slightly better - return Nil
    88 // slightly better - return Nil
    86 def get_contents(name: String) : List[String] = 
    89 def get_contents(name: String) : List[String] = 
    87   Try(Source.fromFile(name).getLines.toList).getOrElse(List())
    90   Try(Source.fromFile(name).getLines.toList).getOrElse(List())
   154 
   157 
   155 // Higher-Order Functions
   158 // Higher-Order Functions
   156 //========================
   159 //========================
   157 
   160 
   158 // functions can take functions as arguments
   161 // functions can take functions as arguments
       
   162 // and produce functions as result
   159 
   163 
   160 def even(x: Int) : Boolean = x % 2 == 0
   164 def even(x: Int) : Boolean = x % 2 == 0
   161 def odd(x: Int) : Boolean = x % 2 == 1
   165 def odd(x: Int) : Boolean = x % 2 == 1
   162 
   166 
   163 val lst = (1 to 10).toList
   167 val lst = (1 to 10).toList
   202 
   206 
   203 lst.map(x => (double(x), square(x)))
   207 lst.map(x => (double(x), square(x)))
   204 
   208 
   205 lst.map(square)
   209 lst.map(square)
   206 
   210 
   207 // this is actually how for-comprehensions 
   211 // this is actually how for-comprehensions are
   208 // defined as in Scala
   212 // defined in Scala
   209 
   213 
   210 lst.map(n => square(n))
   214 lst.map(n => square(n))
   211 for (n <- lst) yield square(n)
   215 for (n <- lst) yield square(n)
   212 
   216 
   213 // this can be iterated
   217 // this can be iterated
   230 
   234 
   231 
   235 
   232 // same function using pattern matching: a kind
   236 // same function using pattern matching: a kind
   233 // of switch statement on steroids (see more later on)
   237 // of switch statement on steroids (see more later on)
   234 
   238 
   235 def my_map_int(lst: List[Int], f: Int => Int) : List[Int] = lst match {
   239 def my_map_int(lst: List[Int], f: Int => Int) : List[Int] = 
       
   240 lst match {
   236   case Nil => Nil
   241   case Nil => Nil
   237   case x::xs => f(x)::my_map_int(xs, f)
   242   case x::xs => f(x)::my_map_int(xs, f)
   238 }
   243 }
   239 
   244 
   240 
   245 
   266 
   271 
   267 
   272 
   268 // sometimes it is needed that you specify the type. 
   273 // sometimes it is needed that you specify the type. 
   269 (1 to 100).filter((x: Int) => x % 2 == 0).sum 
   274 (1 to 100).filter((x: Int) => x % 2 == 0).sum 
   270 
   275 
   271 // in this case it is clear that x mist be an Int
   276 // in this case it is clear that x must be an Int
   272 (1 to 100).filter(x => x % 2 == 0).sum
   277 (1 to 100).filter(x => x % 2 == 0).sum
   273 
   278 
   274 // As each parameter (only x in this case) is passed only once
   279 // When each parameter (only x in this case) is used only once
   275 // you can use the wizardy placeholder syntax
   280 // you can use the wizardy placeholder syntax
   276 (1 to 100).filter(_ % 2 == 0).sum
   281 (1 to 100).filter(_ % 2 == 0).sum
   277 
   282 
   278 
   283 
   279 
   284 
   332 
   337 
   333 val facsMap2 = facsMap + (1 -> List(1,2,3,4,5))
   338 val facsMap2 = facsMap + (1 -> List(1,2,3,4,5))
   334 facsMap.get(1)
   339 facsMap.get(1)
   335 facsMap2.get(1)
   340 facsMap2.get(1)
   336 
   341 
   337 // groupBy function on maps
   342 // groupBy function on Maps
   338 
   343 
   339 val ls = List("one", "two", "three", "four", "five")
   344 val ls = List("one", "two", "three", "four", "five")
   340 ls.groupBy(_.length)
   345 ls.groupBy(_.length)
   341 
   346 
   342 ls.groupBy(_.length).get(3)
   347 ls.groupBy(_.length).get(3)
   359 //       ...
   364 //       ...
   360 //       case patternN => expressionN
   365 //       case patternN => expressionN
   361 //    }
   366 //    }
   362 
   367 
   363 
   368 
   364 
   369 // recall
   365 
       
   366 // remember?
       
   367 val lst = List(None, Some(1), Some(2), None, Some(3)).flatten
   370 val lst = List(None, Some(1), Some(2), None, Some(3)).flatten
   368 
       
   369 
   371 
   370 def my_flatten(xs: List[Option[Int]]): List[Int] = xs match {
   372 def my_flatten(xs: List[Option[Int]]): List[Int] = xs match {
   371   case Nil => Nil 
   373   case Nil => Nil 
   372   case None::rest => my_flatten(rest)
   374   case None::rest => my_flatten(rest)
   373   case Some(v)::rest => v :: my_flatten(rest)
   375   case Some(v)::rest => v :: my_flatten(rest)
   374 }
   376 }
       
   377 
       
   378 my_flatten(List(None, Some(1), Some(2), None, Some(3)))
   375 
   379 
   376 
   380 
   377 // another example with a default case
   381 // another example with a default case
   378 def get_me_a_string(n: Int): String = n match {
   382 def get_me_a_string(n: Int): String = n match {
   379   case 0 | 1 | 2 => "small"
   383   case 0 | 1 | 2 => "small"
   536 
   540 
   537 
   541 
   538 
   542 
   539 
   543 
   540 
   544 
   541 
   545 // Jumping Towers
       
   546 //================
       
   547 
       
   548 
       
   549 def moves(xs: List[Int], n: Int) : List[List[Int]] = (xs, n) match {
       
   550   case (Nil, _) => Nil
       
   551   case (xs, 0) => Nil
       
   552   case (x::xs, n) => (x::xs) :: moves(xs, n - 1)
       
   553 }
       
   554 
       
   555 
       
   556 moves(List(5,1,0), 1)
       
   557 moves(List(5,1,0), 2)
       
   558 moves(List(5,1,0), 5)
       
   559 
       
   560 // checks whether a jump tour exists at all
       
   561 
       
   562 def search(xs: List[Int]) : Boolean = xs match {
       
   563   case Nil => true
       
   564   case (x::xs) =>
       
   565     if (xs.length < x) true else moves(xs, x).exists(search(_))
       
   566 }
       
   567 
       
   568 
       
   569 search(List(5,3,2,5,1,1))
       
   570 search(List(3,5,1,0,0,0,1))
       
   571 search(List(3,5,1,0,0,0,0,1))
       
   572 search(List(3,5,1,0,0,0,1,1))
       
   573 search(List(3,5,1))
       
   574 search(List(5,1,1))
       
   575 search(Nil)
       
   576 search(List(1))
       
   577 search(List(5,1,1))
       
   578 search(List(3,5,1,0,0,0,0,0,0,0,0,1))
       
   579 
       
   580 // generate *all* jump tours
       
   581 //    if we are only interested in the shortes one, we could
       
   582 //    shortcircut the calculation and only return List(x) in
       
   583 //    case where xs.length < x, because no tour can be shorter
       
   584 //    than 1
       
   585 // 
       
   586 
       
   587 def jumps(xs: List[Int]) : List[List[Int]] = xs match {
       
   588   case Nil => Nil
       
   589   case (x::xs) => {
       
   590     val children = moves(xs, x)
       
   591     val results = children.map(cs => jumps(cs).map(x :: _)).flatten
       
   592     if (xs.length < x) List(x) :: results else results
       
   593   }
       
   594 }
       
   595 
       
   596 jumps(List(3,5,1,2,1,2,1))
       
   597 jumps(List(3,5,1,2,3,4,1))
       
   598 jumps(List(3,5,1,0,0,0,1))
       
   599 jumps(List(3,5,1))
       
   600 jumps(List(5,1,1))
       
   601 jumps(Nil)
       
   602 jumps(List(1))
       
   603 jumps(List(5,1,2))
       
   604 moves(List(1,2), 5)
       
   605 jumps(List(1,5,1,2))
       
   606 jumps(List(3,5,1,0,0,0,0,0,0,0,0,1))
       
   607 
       
   608 jumps(List(5,3,2,5,1,1)).minBy(_.length)
       
   609 jumps(List(1,3,5,8,9,2,6,7,6,8,9)).minBy(_.length)
       
   610 jumps(List(1,3,6,1,0,9)).minBy(_.length)
       
   611 jumps(List(2,3,1,1,2,4,2,0,1,1)).minBy(_.length)
       
   612 
       
   613 
       
   614