diff -r 9e0216756771 -r e43f7e92ba26 progs/lecture2.scala --- 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)