progs/lecture2.scala
changeset 268 e43f7e92ba26
parent 266 ca48ac1d3c3e
child 278 0c2481cd8b1c
--- a/progs/lecture2.scala	Wed Jul 24 15:18:44 2019 +0100
+++ b/progs/lecture2.scala	Thu Aug 01 09:48:34 2019 +0100
@@ -18,9 +18,7 @@
 time_needed(10, for (n <- list) yield n + 42)
 time_needed(10, for (n <- list.par) yield n + 42)
 
-// (ONLY WORKS OUT-OF-THE-BOX IN SCALA 2.11.8, not in SCALA 2.12)
-// (would need to have this wrapped into a function, or
-//  REPL called with scala -Yrepl-class-based)
+// (needs a library and 'magic' option -Yrepl-class-based)
 
 
 // Just for Fun: Mutable vs Immutable
@@ -124,7 +122,8 @@
 
 lst.map(square)
 
-// this is actually what for is defined at in Scala
+// this is actually how for-comprehensions 
+// defined as in Scala
 
 lst.map(n => square(n))
 for (n <- lst) yield square(n)
@@ -227,12 +226,13 @@
 
 
 
-// Option type
-//=============
+// Option type (again)
+//=====================
 
-//in Java if something unusually happens, you return null;
+// remember, in Java if something unusually happens, 
+// you return null;
 //
-//in Scala you use Option
+// in Scala you use Option
 //   - if the value is present, you use Some(value)
 //   - if no value is present, you use None
 
@@ -295,7 +295,7 @@
 val lst = List("12345", "foo", "5432", "bar", "x21", "456")
 for (x <- lst) yield get_me_an_int(x)
 
-// summing all the numbers
+// summing up all the numbers
 
 lst.map(get_me_an_int).flatten.sum
 lst.map(get_me_an_int).flatten.sum
@@ -419,7 +419,7 @@
 fav_colour(Green)
 
 
-// ... a bit more useful: Roman Numerals
+// ... a tiny bit more useful: Roman Numerals
 
 abstract class RomanDigit 
 case object I extends RomanDigit 
@@ -434,6 +434,7 @@
 
 List(X,I)
 
+/*
 I -> 1
 II -> 2
 III  -> 3
@@ -444,6 +445,7 @@
 VIII -> 8
 IX -> 9
 X -> X
+*/
 
 def RomanNumeral2Int(rs: RomanNumeral): Int = rs match { 
   case Nil => 0
@@ -510,10 +512,8 @@
 
 println(people.sortWith(superior).mkString("\n"))
 
-print("123\\n456")
 
-
-// Tail recursion
+// Tail Recursion
 //================
 
 
@@ -565,6 +565,7 @@
 val http_pattern = """"https?://[^"]*"""".r
 val email_pattern = """([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})""".r
 
+//test case:
 //email_pattern.findAllIn
 //  ("foo bla christian@kcl.ac.uk 1234567").toList
 
@@ -617,54 +618,57 @@
               |..7.9.41.""".stripMargin.replaceAll("\\n", "")
 
 type Pos = (Int, Int)
-val EmptyValue = '.'
-val MaxValue = 9
+val emptyValue = '.'
+val maxValue = 9
 
 val allValues = "123456789".toList
 val indexes = (0 to 8).toList
 
 
+def empty(game: String) = game.indexOf(emptyValue)
+def isDone(game: String) = empty(game) == -1 
+def emptyPosition(game: String) : Pos = 
+  (empty(game) % maxValue, empty(game) / maxValue)
 
 
-def empty(game: String) = game.indexOf(EmptyValue)
-def isDone(game: String) = empty(game) == -1 
-def emptyPosition(game: String) = (empty(game) % MaxValue, empty(game) / MaxValue)
-
-
-def get_row(game: String, y: Int) = indexes.map(col => game(y * MaxValue + col))
-def get_col(game: String, x: Int) = indexes.map(row => game(x + row * MaxValue))
+def get_row(game: String, y: Int) = indexes.map(col => game(y * maxValue + col))
+def get_col(game: String, x: Int) = indexes.map(row => game(x + row * maxValue))
 
 def get_box(game: String, pos: Pos): List[Char] = {
     def base(p: Int): Int = (p / 3) * 3
     val x0 = base(pos._1)
     val y0 = base(pos._2)
-    val ys = (y0 until y0 + 3).toList
-    (x0 until x0 + 3).toList.flatMap(x => ys.map(y => game(x + y * MaxValue)))
-}
+    for (x <- (x0 until x0 + 3).toList;
+         y <- (y0 until y0 + 3).toList) yield game(x + y * maxValue)
+}         
 
 
 //get_row(game0, 0)
 //get_row(game0, 1)
 //get_box(game0, (3,1))
 
-def update(game: String, pos: Int, value: Char): String = game.updated(pos, value)
+def update(game: String, pos: Int, value: Char): String = 
+  game.updated(pos, value)
 
 def toAvoid(game: String, pos: Pos): List[Char] = 
   (get_col(game, pos._1) ++ get_row(game, pos._2) ++ get_box(game, pos))
 
-def candidates(game: String, pos: Pos): List[Char] = allValues diff toAvoid(game,pos)
+def candidates(game: String, pos: Pos): List[Char] = 
+  allValues.diff(toAvoid(game, pos))
 
-//candidates(game0, (0,0))
+//candidates(game0, (0, 0))
 
-def pretty(game: String): String = "\n" + (game sliding (MaxValue, MaxValue) mkString "\n")
+def pretty(game: String): String = 
+  "\n" ++ (game.sliding(maxValue, maxValue).mkString("\n"))
 
 def search(game: String): List[String] = {
   if (isDone(game)) List(game)
   else 
-    candidates(game, emptyPosition(game)).map(c => search(update(game, empty(game), c))).toList.flatten
+    candidates(game, emptyPosition(game)).
+      map(c => search(update(game, empty(game), c))).flatten
 }
 
-
+// an easy game
 val game1 = """23.915...
               |...2..54.
               |6.7......
@@ -676,7 +680,7 @@
               |...329..1""".stripMargin.replaceAll("\\n", "")
 
 
-// game that is in the hard category
+// a game that is in the sligtly harder category
 val game2 = """8........
               |..36.....
               |.7..9.2..
@@ -687,7 +691,7 @@
               |..85...1.
               |.9....4..""".stripMargin.replaceAll("\\n", "")
 
-// game with multiple solutions
+// a game with multiple solutions
 val game3 = """.8...9743
               |.5...8.1.
               |.1.......
@@ -707,7 +711,7 @@
   val start = System.nanoTime()
   for (j <- 1 to i) code
   val end = System.nanoTime()
-  ((end - start) / i / 1.0e9) + " secs"
+  s"${(end - start) / i / 1.0e9} secs"
 }
 
 search(game2).map(pretty)