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)) |