progs/lecture2.scala
changeset 319 b84ea52bfd8f
parent 318 029e2862bb4e
child 320 cdfb2ce30a3d
--- a/progs/lecture2.scala	Tue Nov 12 00:41:00 2019 +0000
+++ b/progs/lecture2.scala	Tue Nov 12 10:47:27 2019 +0000
@@ -75,11 +75,14 @@
 // the same for files
 Try(Some(Source.fromFile("text.txt").mkString)).getOrElse(None)
 
-// how to implement a function for reading something from files...
 
+// how to implement a function for reading 
+// (lines) something from files...
+//
 def get_contents(name: String) : List[String] = 
   Source.fromFile(name).getLines.toList
 
+get_contents("text.txt")
 get_contents("test.txt")
 
 // slightly better - return Nil
@@ -156,6 +159,7 @@
 //========================
 
 // functions can take functions as arguments
+// and produce functions as result
 
 def even(x: Int) : Boolean = x % 2 == 0
 def odd(x: Int) : Boolean = x % 2 == 1
@@ -204,8 +208,8 @@
 
 lst.map(square)
 
-// this is actually how for-comprehensions 
-// defined as in Scala
+// this is actually how for-comprehensions are
+// defined in Scala
 
 lst.map(n => square(n))
 for (n <- lst) yield square(n)
@@ -232,7 +236,8 @@
 // same function using pattern matching: a kind
 // of switch statement on steroids (see more later on)
 
-def my_map_int(lst: List[Int], f: Int => Int) : List[Int] = lst match {
+def my_map_int(lst: List[Int], f: Int => Int) : List[Int] = 
+lst match {
   case Nil => Nil
   case x::xs => f(x)::my_map_int(xs, f)
 }
@@ -268,10 +273,10 @@
 // sometimes it is needed that you specify the type. 
 (1 to 100).filter((x: Int) => x % 2 == 0).sum 
 
-// in this case it is clear that x mist be an Int
+// in this case it is clear that x must be an Int
 (1 to 100).filter(x => x % 2 == 0).sum
 
-// As each parameter (only x in this case) is passed only once
+// When each parameter (only x in this case) is used only once
 // you can use the wizardy placeholder syntax
 (1 to 100).filter(_ % 2 == 0).sum
 
@@ -334,7 +339,7 @@
 facsMap.get(1)
 facsMap2.get(1)
 
-// groupBy function on maps
+// groupBy function on Maps
 
 val ls = List("one", "two", "three", "four", "five")
 ls.groupBy(_.length)
@@ -361,18 +366,17 @@
 //    }
 
 
-
-
-// remember?
+// recall
 val lst = List(None, Some(1), Some(2), None, Some(3)).flatten
 
-
 def my_flatten(xs: List[Option[Int]]): List[Int] = xs match {
   case Nil => Nil 
   case None::rest => my_flatten(rest)
   case Some(v)::rest => v :: my_flatten(rest)
 }
 
+my_flatten(List(None, Some(1), Some(2), None, Some(3)))
+
 
 // another example with a default case
 def get_me_a_string(n: Int): String = n match {
@@ -538,4 +542,73 @@
 
 
 
+// Jumping Towers
+//================
 
+
+def moves(xs: List[Int], n: Int) : List[List[Int]] = (xs, n) match {
+  case (Nil, _) => Nil
+  case (xs, 0) => Nil
+  case (x::xs, n) => (x::xs) :: moves(xs, n - 1)
+}
+
+
+moves(List(5,1,0), 1)
+moves(List(5,1,0), 2)
+moves(List(5,1,0), 5)
+
+// checks whether a jump tour exists at all
+
+def search(xs: List[Int]) : Boolean = xs match {
+  case Nil => true
+  case (x::xs) =>
+    if (xs.length < x) true else moves(xs, x).exists(search(_))
+}
+
+
+search(List(5,3,2,5,1,1))
+search(List(3,5,1,0,0,0,1))
+search(List(3,5,1,0,0,0,0,1))
+search(List(3,5,1,0,0,0,1,1))
+search(List(3,5,1))
+search(List(5,1,1))
+search(Nil)
+search(List(1))
+search(List(5,1,1))
+search(List(3,5,1,0,0,0,0,0,0,0,0,1))
+
+// generate *all* jump tours
+//    if we are only interested in the shortes one, we could
+//    shortcircut the calculation and only return List(x) in
+//    case where xs.length < x, because no tour can be shorter
+//    than 1
+// 
+
+def jumps(xs: List[Int]) : List[List[Int]] = xs match {
+  case Nil => Nil
+  case (x::xs) => {
+    val children = moves(xs, x)
+    val results = children.map(cs => jumps(cs).map(x :: _)).flatten
+    if (xs.length < x) List(x) :: results else results
+  }
+}
+
+jumps(List(3,5,1,2,1,2,1))
+jumps(List(3,5,1,2,3,4,1))
+jumps(List(3,5,1,0,0,0,1))
+jumps(List(3,5,1))
+jumps(List(5,1,1))
+jumps(Nil)
+jumps(List(1))
+jumps(List(5,1,2))
+moves(List(1,2), 5)
+jumps(List(1,5,1,2))
+jumps(List(3,5,1,0,0,0,0,0,0,0,0,1))
+
+jumps(List(5,3,2,5,1,1)).minBy(_.length)
+jumps(List(1,3,5,8,9,2,6,7,6,8,9)).minBy(_.length)
+jumps(List(1,3,6,1,0,9)).minBy(_.length)
+jumps(List(2,3,1,1,2,4,2,0,1,1)).minBy(_.length)
+
+
+