16   | 
    16   | 
    17 val list = (1 to 1000000).toList  | 
    17 val list = (1 to 1000000).toList  | 
    18 time_needed(10, for (n <- list) yield n + 42)  | 
    18 time_needed(10, for (n <- list) yield n + 42)  | 
    19 time_needed(10, for (n <- list.par) yield n + 42)  | 
    19 time_needed(10, for (n <- list.par) yield n + 42)  | 
    20   | 
    20   | 
    21 // (ONLY WORKS OUT-OF-THE-BOX IN SCALA 2.11.8, not in SCALA 2.12)  | 
    21 // (needs a library and 'magic' option -Yrepl-class-based)  | 
    22 // (would need to have this wrapped into a function, or  | 
         | 
    23 //  REPL called with scala -Yrepl-class-based)  | 
         | 
    24   | 
    22   | 
    25   | 
    23   | 
    26 // Just for Fun: Mutable vs Immutable  | 
    24 // Just for Fun: Mutable vs Immutable  | 
    27 //====================================  | 
    25 //====================================  | 
    28 //  | 
    26 //  | 
   225   | 
   224   | 
   226 ls.groupBy(_.length).get(2)  | 
   225 ls.groupBy(_.length).get(2)  | 
   227   | 
   226   | 
   228   | 
   227   | 
   229   | 
   228   | 
   230 // Option type  | 
   229 // Option type (again)  | 
   231 //=============  | 
   230 //=====================  | 
   232   | 
   231   | 
   233 //in Java if something unusually happens, you return null;  | 
   232 // remember, in Java if something unusually happens,   | 
         | 
   233 // you return null;  | 
   234 //  | 
   234 //  | 
   235 //in Scala you use Option  | 
   235 // in Scala you use Option  | 
   236 //   - if the value is present, you use Some(value)  | 
   236 //   - if the value is present, you use Some(value)  | 
   237 //   - if no value is present, you use None  | 
   237 //   - if no value is present, you use None  | 
   238   | 
   238   | 
   239   | 
   239   | 
   240 List(7,2,3,4,5,6).find(_ < 4)  | 
   240 List(7,2,3,4,5,6).find(_ < 4)  | 
   293  Try(Some(Integer.parseInt(s))).getOrElse(None)  | 
   293  Try(Some(Integer.parseInt(s))).getOrElse(None)  | 
   294   | 
   294   | 
   295 val lst = List("12345", "foo", "5432", "bar", "x21", "456") | 
   295 val lst = List("12345", "foo", "5432", "bar", "x21", "456") | 
   296 for (x <- lst) yield get_me_an_int(x)  | 
   296 for (x <- lst) yield get_me_an_int(x)  | 
   297   | 
   297   | 
   298 // summing all the numbers  | 
   298 // summing up all the numbers  | 
   299   | 
   299   | 
   300 lst.map(get_me_an_int).flatten.sum  | 
   300 lst.map(get_me_an_int).flatten.sum  | 
   301 lst.map(get_me_an_int).flatten.sum  | 
   301 lst.map(get_me_an_int).flatten.sum  | 
   302   | 
   302   | 
   303   | 
   303   | 
   615               |..6.2..3.  | 
   616               |..6.2..3.  | 
   616               |1..5...92  | 
   617               |1..5...92  | 
   617               |..7.9.41.""".stripMargin.replaceAll("\\n", "") | 
   618               |..7.9.41.""".stripMargin.replaceAll("\\n", "") | 
   618   | 
   619   | 
   619 type Pos = (Int, Int)  | 
   620 type Pos = (Int, Int)  | 
   620 val EmptyValue = '.'  | 
   621 val emptyValue = '.'  | 
   621 val MaxValue = 9  | 
   622 val maxValue = 9  | 
   622   | 
   623   | 
   623 val allValues = "123456789".toList  | 
   624 val allValues = "123456789".toList  | 
   624 val indexes = (0 to 8).toList  | 
   625 val indexes = (0 to 8).toList  | 
   625   | 
   626   | 
   626   | 
   627   | 
   627   | 
   628 def empty(game: String) = game.indexOf(emptyValue)  | 
   628   | 
         | 
   629 def empty(game: String) = game.indexOf(EmptyValue)  | 
         | 
   630 def isDone(game: String) = empty(game) == -1   | 
   629 def isDone(game: String) = empty(game) == -1   | 
   631 def emptyPosition(game: String) = (empty(game) % MaxValue, empty(game) / MaxValue)  | 
   630 def emptyPosition(game: String) : Pos =   | 
   632   | 
   631   (empty(game) % maxValue, empty(game) / maxValue)  | 
   633   | 
   632   | 
   634 def get_row(game: String, y: Int) = indexes.map(col => game(y * MaxValue + col))  | 
   633   | 
   635 def get_col(game: String, x: Int) = indexes.map(row => game(x + row * MaxValue))  | 
   634 def get_row(game: String, y: Int) = indexes.map(col => game(y * maxValue + col))  | 
         | 
   635 def get_col(game: String, x: Int) = indexes.map(row => game(x + row * maxValue))  | 
   636   | 
   636   | 
   637 def get_box(game: String, pos: Pos): List[Char] = { | 
   637 def get_box(game: String, pos: Pos): List[Char] = { | 
   638     def base(p: Int): Int = (p / 3) * 3  | 
   638     def base(p: Int): Int = (p / 3) * 3  | 
   639     val x0 = base(pos._1)  | 
   639     val x0 = base(pos._1)  | 
   640     val y0 = base(pos._2)  | 
   640     val y0 = base(pos._2)  | 
   641     val ys = (y0 until y0 + 3).toList  | 
   641     for (x <- (x0 until x0 + 3).toList;  | 
   642     (x0 until x0 + 3).toList.flatMap(x => ys.map(y => game(x + y * MaxValue)))  | 
   642          y <- (y0 until y0 + 3).toList) yield game(x + y * maxValue)  | 
   643 }  | 
   643 }           | 
   644   | 
   644   | 
   645   | 
   645   | 
   646 //get_row(game0, 0)  | 
   646 //get_row(game0, 0)  | 
   647 //get_row(game0, 1)  | 
   647 //get_row(game0, 1)  | 
   648 //get_box(game0, (3,1))  | 
   648 //get_box(game0, (3,1))  | 
   649   | 
   649   | 
   650 def update(game: String, pos: Int, value: Char): String = game.updated(pos, value)  | 
   650 def update(game: String, pos: Int, value: Char): String =   | 
         | 
   651   game.updated(pos, value)  | 
   651   | 
   652   | 
   652 def toAvoid(game: String, pos: Pos): List[Char] =   | 
   653 def toAvoid(game: String, pos: Pos): List[Char] =   | 
   653   (get_col(game, pos._1) ++ get_row(game, pos._2) ++ get_box(game, pos))  | 
   654   (get_col(game, pos._1) ++ get_row(game, pos._2) ++ get_box(game, pos))  | 
   654   | 
   655   | 
   655 def candidates(game: String, pos: Pos): List[Char] = allValues diff toAvoid(game,pos)  | 
   656 def candidates(game: String, pos: Pos): List[Char] =   | 
   656   | 
   657   allValues.diff(toAvoid(game, pos))  | 
   657 //candidates(game0, (0,0))  | 
   658   | 
   658   | 
   659 //candidates(game0, (0, 0))  | 
   659 def pretty(game: String): String = "\n" + (game sliding (MaxValue, MaxValue) mkString "\n")  | 
   660   | 
         | 
   661 def pretty(game: String): String =   | 
         | 
   662   "\n" ++ (game.sliding(maxValue, maxValue).mkString("\n")) | 
   660   | 
   663   | 
   661 def search(game: String): List[String] = { | 
   664 def search(game: String): List[String] = { | 
   662   if (isDone(game)) List(game)  | 
   665   if (isDone(game)) List(game)  | 
   663   else   | 
   666   else   | 
   664     candidates(game, emptyPosition(game)).map(c => search(update(game, empty(game), c))).toList.flatten  | 
   667     candidates(game, emptyPosition(game)).  | 
   665 }  | 
   668       map(c => search(update(game, empty(game), c))).flatten  | 
   666   | 
   669 }  | 
   667   | 
   670   | 
         | 
   671 // an easy game  | 
   668 val game1 = """23.915...  | 
   672 val game1 = """23.915...  | 
   669               |...2..54.  | 
   673               |...2..54.  | 
   670               |6.7......  | 
   674               |6.7......  | 
   671               |..1.....9  | 
   675               |..1.....9  | 
   672               |89.5.3.17  | 
   676               |89.5.3.17  | 
   705 // for measuring time  | 
   709 // for measuring time  | 
   706 def time_needed[T](i: Int, code: => T) = { | 
   710 def time_needed[T](i: Int, code: => T) = { | 
   707   val start = System.nanoTime()  | 
   711   val start = System.nanoTime()  | 
   708   for (j <- 1 to i) code  | 
   712   for (j <- 1 to i) code  | 
   709   val end = System.nanoTime()  | 
   713   val end = System.nanoTime()  | 
   710   ((end - start) / i / 1.0e9) + " secs"  | 
   714   s"${(end - start) / i / 1.0e9} secs" | 
   711 }  | 
   715 }  | 
   712   | 
   716   | 
   713 search(game2).map(pretty)  | 
   717 search(game2).map(pretty)  | 
   714 search(game3).distinct.length  | 
   718 search(game3).distinct.length  | 
   715 time_needed(3, search(game2))  | 
   719 time_needed(3, search(game2))  |