|    119 val lst = List(None, Some(1), Some(2), None, Some(3)) |    122 val lst = List(None, Some(1), Some(2), None, Some(3)) | 
|    120  |    123  | 
|    121 for (x <- lst) yield x.getOrElse(0) |    124 for (x <- lst) yield x.getOrElse(0) | 
|    122  |    125  | 
|    123  |    126  | 
|         |    127 // a function that turns strings into numbers (similar to .toInt) | 
|         |    128 Integer.parseInt("1234") | 
|         |    129  | 
|         |    130  | 
|         |    131 def get_me_an_int(s: String) : Option[Int] =  | 
|         |    132  Try(Some(Integer.parseInt(s))).getOrElse(None) | 
|    124  |    133  | 
|    125  |    134  | 
|    126 // This may not look any better than working with null in Java, but to |    135 // This may not look any better than working with null in Java, but to | 
|    127 // see the value, you have to put yourself in the shoes of the |    136 // see the value, you have to put yourself in the shoes of the | 
|    128 // consumer of the get_me_an_int function, and imagine you didn't |    137 // consumer of the get_me_an_int function, and imagine you didn't | 
|    129 // write that function. |    138 // write that function. | 
|    130 // |    139 // | 
|    131 // In Java, if you didn't write this function, you'd have to depend on |    140 // In Java, if you didn't write this function, you'd have to depend on | 
|    132 // the Javadoc of the get_me_an_int. If you didn't look at the Javadoc,  |    141 // the Javadoc of the get_me_an_int. If you didn't look at the Javadoc,  | 
|    133 // you might not know that get_me_an_int could return a null, and your  |    142 // you might not know that get_me_an_int could return null, and your  | 
|    134 // code could potentially throw a NullPointerException. |    143 // code could potentially throw a NullPointerException. | 
|    135  |         | 
|    136  |    144  | 
|    137  |    145  | 
|    138 // even Scala is not immune to problems like this: |    146 // even Scala is not immune to problems like this: | 
|    139  |    147  | 
|    140 List(5,6,7,8,9).indexOf(7) |    148 List(5,6,7,8,9).indexOf(7) | 
|    152 def even(x: Int) : Boolean = x % 2 == 0 |    160 def even(x: Int) : Boolean = x % 2 == 0 | 
|    153 def odd(x: Int) : Boolean = x % 2 == 1 |    161 def odd(x: Int) : Boolean = x % 2 == 1 | 
|    154  |    162  | 
|    155 val lst = (1 to 10).toList |    163 val lst = (1 to 10).toList | 
|    156  |    164  | 
|    157 lst.filter(x => even(x)) |         | 
|    158 lst.filter(even(_)) |         | 
|    159 lst.filter(even) |    165 lst.filter(even) | 
|    160  |         | 
|    161 lst.count(even) |    166 lst.count(even) | 
|    162  |         | 
|    163  |         | 
|    164 lst.find(even) |    167 lst.find(even) | 
|    165  |    168  | 
|    166 val ps = List((3, 0), (3, 2), (4, 2), (2, 2), (2, 0), (1, 1), (1, 0)) |    169 lst.filter(x => x % 2 == 0) | 
|         |    170 lst.filter(_ % 2 == 0) | 
|    167  |    171  | 
|    168 lst.sortWith(_ > _) |    172 lst.sortWith(_ > _) | 
|    169 lst.sortWith(_ < _) |    173 lst.sortWith(_ < _) | 
|    170  |    174  | 
|         |    175 // but this only works when the arguments are clear, but  | 
|         |    176 // not with multiple occurences | 
|         |    177 lst.find(n => odd(n) && n > 2) | 
|         |    178  | 
|         |    179  | 
|         |    180 val ps = List((3, 0), (3, 2), (4, 2), (2, 2), (2, 0), (1, 1), (1, 0)) | 
|         |    181  | 
|    171 def lex(x: (Int, Int), y: (Int, Int)) : Boolean =  |    182 def lex(x: (Int, Int), y: (Int, Int)) : Boolean =  | 
|    172   if (x._1 == y._1) x._2 < y._2 else x._1 < y._1 |    183   if (x._1 == y._1) x._2 < y._2 else x._1 < y._1 | 
|    173  |    184  | 
|    174 ps.sortWith(lex) |    185 ps.sortWith(lex) | 
|    175  |    186  | 
|    245 def sum_cubes(lst: List[Int])   = sumOf(x => x * x * x, lst) |    254 def sum_cubes(lst: List[Int])   = sumOf(x => x * x * x, lst) | 
|    246  |    255  | 
|    247 sum_squares(lst) |    256 sum_squares(lst) | 
|    248 sum_cubes(lst) |    257 sum_cubes(lst) | 
|    249  |    258  | 
|    250 // lets try it factorial |    259 // lets try a factorial | 
|    251 def fact(n: Int) : Int =  |    260 def fact(n: Int) : Int =  | 
|    252   if (n == 0) 1 else n * fact(n - 1) |    261   if (n == 0) 1 else n * fact(n - 1) | 
|    253  |    262  | 
|    254 def sum_fact(lst: List[Int]) = sumOf(fact, lst) |    263 def sum_fact(lst: List[Int]) = sumOf(fact, lst) | 
|    255 sum_fact(lst) |    264 sum_fact(lst) | 
|    256  |    265  | 
|    257  |    266  | 
|    258  |    267  | 
|    259 // if you like verbosity, you can full-specify the literal.  |    268 // sometimes it is needed that you specify the type.  | 
|    260 // Don't go telling that to people, though |         | 
|    261 (1 to 100).filter((x: Int) => x % 2 == 0).sum  |    269 (1 to 100).filter((x: Int) => x % 2 == 0).sum  | 
|    262  |    270  | 
|    263 // As x is known to be an Int anyway, you can omit that part |    271 // in this case it is clear that x mist be an Int | 
|    264 (1 to 100).filter(x => x % 2 == 0).sum |    272 (1 to 100).filter(x => x % 2 == 0).sum | 
|    265  |    273  | 
|    266 // As each parameter (only x in this case) is passed only once |    274 // As each parameter (only x in this case) is passed only once | 
|    267 // you can use the wizardy placeholder syntax |    275 // you can use the wizardy placeholder syntax | 
|    268 (1 to 100).filter(_ % 2 == 0).sum |    276 (1 to 100).filter(_ % 2 == 0).sum | 
|    269  |    277  | 
|    270 // But if you want to re-use your literal, you can also put it in a value |    278  | 
|    271 // In this case, explicit types are required because there's nothing to infer from |    279  | 
|    272 val isEven = (x: Int) => x % 2 == 0 |    280 // Option Type and maps | 
|    273 (1 to 100).filter(isEven).sum |    281 //====================== | 
|    274  |         | 
|    275  |         | 
|    276  |         | 
|    277 // Option Type again |         | 
|    278 //=================== |         | 
|    279  |    282  | 
|    280 // a function that turns strings into numbers (similar to .toInt) |    283 // a function that turns strings into numbers (similar to .toInt) | 
|    281 Integer.parseInt("12u34") |    284 Integer.parseInt("12u34") | 
|    282  |    285  | 
|         |    286 import scala.util._ | 
|    283  |    287  | 
|    284 def get_me_an_int(s: String) : Option[Int] =  |    288 def get_me_an_int(s: String) : Option[Int] =  | 
|    285  Try(Some(Integer.parseInt(s))).getOrElse(None) |    289  Try(Some(Integer.parseInt(s))).getOrElse(None) | 
|    286  |    290  | 
|    287 val lst = List("12345", "foo", "5432", "bar", "x21", "456") |    291 val lst = List("12345", "foo", "5432", "bar", "x21", "456") | 
|    413  |    415  | 
|    414 for (n <- 0 to 20)  |    416 for (n <- 0 to 20)  | 
|    415  println(fizz_buzz(n)) |    417  println(fizz_buzz(n)) | 
|    416  |    418  | 
|    417  |    419  | 
|    418 // User-defined Datatypes |         | 
|    419 //======================== |         | 
|    420  |         | 
|    421  |         | 
|    422 abstract class Colour |         | 
|    423 case object Red extends Colour  |         | 
|    424 case object Green extends Colour  |         | 
|    425 case object Blue extends Colour |         | 
|    426  |         | 
|    427 def fav_colour(c: Colour) : Boolean = c match { |         | 
|    428   case Red   => false |         | 
|    429   case Green => true |         | 
|    430   case Blue  => false  |         | 
|    431 } |         | 
|    432  |         | 
|    433 fav_colour(Green) |         | 
|    434  |         | 
|    435  |         | 
|    436 // ... a tiny bit more useful: Roman Numerals |         | 
|    437  |         | 
|    438 abstract class RomanDigit  |         | 
|    439 case object I extends RomanDigit  |         | 
|    440 case object V extends RomanDigit  |         | 
|    441 case object X extends RomanDigit  |         | 
|    442 case object L extends RomanDigit  |         | 
|    443 case object C extends RomanDigit  |         | 
|    444 case object D extends RomanDigit  |         | 
|    445 case object M extends RomanDigit  |         | 
|    446  |         | 
|    447 type RomanNumeral = List[RomanDigit]  |         | 
|    448  |         | 
|    449 List(X,I) |         | 
|    450  |         | 
|    451 /* |         | 
|    452 I -> 1 |         | 
|    453 II -> 2 |         | 
|    454 III  -> 3 |         | 
|    455 IV -> 4 |         | 
|    456 V -> 5 |         | 
|    457 VI -> 6 |         | 
|    458 VII -> 7 |         | 
|    459 VIII -> 8 |         | 
|    460 IX -> 9 |         | 
|    461 X -> X |         | 
|    462 */ |         | 
|    463  |         | 
|    464 def RomanNumeral2Int(rs: RomanNumeral): Int = rs match {  |         | 
|    465   case Nil => 0 |         | 
|    466   case M::r    => 1000 + RomanNumeral2Int(r)   |         | 
|    467   case C::M::r => 900 + RomanNumeral2Int(r) |         | 
|    468   case D::r    => 500 + RomanNumeral2Int(r) |         | 
|    469   case C::D::r => 400 + RomanNumeral2Int(r) |         | 
|    470   case C::r    => 100 + RomanNumeral2Int(r) |         | 
|    471   case X::C::r => 90 + RomanNumeral2Int(r) |         | 
|    472   case L::r    => 50 + RomanNumeral2Int(r) |         | 
|    473   case X::L::r => 40 + RomanNumeral2Int(r) |         | 
|    474   case X::r    => 10 + RomanNumeral2Int(r) |         | 
|    475   case I::X::r => 9 + RomanNumeral2Int(r) |         | 
|    476   case V::r    => 5 + RomanNumeral2Int(r) |         | 
|    477   case I::V::r => 4 + RomanNumeral2Int(r) |         | 
|    478   case I::r    => 1 + RomanNumeral2Int(r) |         | 
|    479 } |         | 
|    480  |         | 
|    481 RomanNumeral2Int(List(I,V))             // 4 |         | 
|    482 RomanNumeral2Int(List(I,I,I,I))         // 4 (invalid Roman number) |         | 
|    483 RomanNumeral2Int(List(V,I))             // 6 |         | 
|    484 RomanNumeral2Int(List(I,X))             // 9 |         | 
|    485 RomanNumeral2Int(List(M,C,M,L,X,X,I,X)) // 1979 |         | 
|    486 RomanNumeral2Int(List(M,M,X,V,I,I))     // 2017 |         | 
|    487  |         | 
|    488  |         | 
|    489 // another example |         | 
|    490 //================= |         | 
|    491  |         | 
|    492 // Once upon a time, in a complete fictional  |         | 
|    493 // country there were Persons... |         | 
|    494  |         | 
|    495  |         | 
|    496 abstract class Person |         | 
|    497 case object King extends Person |         | 
|    498 case class Peer(deg: String, terr: String, succ: Int) extends Person |         | 
|    499 case class Knight(name: String) extends Person |         | 
|    500 case class Peasant(name: String) extends Person |         | 
|    501  |         | 
|    502  |         | 
|    503 def title(p: Person): String = p match { |         | 
|    504   case King => "His Majesty the King" |         | 
|    505   case Peer(deg, terr, _) => s"The ${deg} of ${terr}" |         | 
|    506   case Knight(name) => s"Sir ${name}" |         | 
|    507   case Peasant(name) => name |         | 
|    508 } |         | 
|    509  |         | 
|    510 def superior(p1: Person, p2: Person): Boolean = (p1, p2) match { |         | 
|    511   case (King, _) => true |         | 
|    512   case (Peer(_,_,_), Knight(_)) => true |         | 
|    513   case (Peer(_,_,_), Peasant(_)) => true |         | 
|    514   case (Peer(_,_,_), Clown) => true |         | 
|    515   case (Knight(_), Peasant(_)) => true |         | 
|    516   case (Knight(_), Clown) => true |         | 
|    517   case (Clown, Peasant(_)) => true |         | 
|    518   case _ => false |         | 
|    519 } |         | 
|    520  |         | 
|    521 val people = List(Knight("David"),  |         | 
|    522                   Peer("Duke", "Norfolk", 84),  |         | 
|    523                   Peasant("Christian"),  |         | 
|    524                   King,  |         | 
|    525                   Clown) |         | 
|    526  |         | 
|    527 println(people.sortWith(superior).mkString("\n")) |         | 
|    528  |         | 
|    529  |         | 
|    530 // String interpolations as patterns |         | 
|    531  |         | 
|    532 val date = "2000-01-01" |         | 
|    533 val s"$year-$month-$day" = date |         | 
|    534  |         | 
|    535 def parse_date(date: String) = date match { |         | 
|    536   case s"$year-$month-$day" => Some((year.toInt, month.toInt, day.toInt)) |         | 
|    537   case s"$day/$month/$year" => Some((year.toInt, month.toInt, day.toInt)) |         | 
|    538   case _ => None |         | 
|    539 }  |         | 
|    540  |    420  | 
|    541  |    421  | 
|    542 // Recursion |    422 // Recursion | 
|    543 //=========== |    423 //=========== | 
|    544  |    424  | 
|    545 /* a, b, c |    425 // well-known example | 
|    546  |    426  | 
|    547 aa         aaa |    427 def fib(n: Int) : Int = {  | 
|    548 ab         baa  |    428   if (n == 0 || n == 1) 1 | 
|    549 ac         caa  |    429    else fib(n - 1) + fib(n - 2) | 
|    550 ba  =>     ...... |    430 } | 
|    551 bb |    431  | 
|    552 bc |    432  | 
|    553 ca |    433 /* Say you have characters a, b, c. | 
|    554 cb |    434    What are all the combinations of a certain length? | 
|    555 cc |    435  | 
|    556  |    436    All combinations of length 2: | 
|         |    437    | 
|         |    438      aa, ab, ac, ba, bb, bc, ca, cb, cc | 
|         |    439  | 
|         |    440    Combinations of length 3: | 
|         |    441     | 
|         |    442      aaa, baa, caa, and so on...... | 
|    557 */ |    443 */ | 
|    558  |    444  | 
|    559 def perms(cs: List[Char], l: Int) : List[String] = { |    445 def combs(cs: List[Char], l: Int) : List[String] = { | 
|    560   if (l == 0) List("") |    446   if (l == 0) List("") | 
|    561   else for (c <- cs; s <- perms(cs, l - 1)) yield s"$c$s" |    447   else for (c <- cs; s <- combs(cs, l - 1)) yield s"$c$s" | 
|    562 } |    448 } | 
|    563  |    449  | 
|    564 perms("abc".toList, 2) |    450 combs("abc".toList, 2) | 
|         |    451  | 
|         |    452  | 
|         |    453 // another well-known example | 
|    565  |    454  | 
|    566 def move(from: Char, to: Char) = |    455 def move(from: Char, to: Char) = | 
|    567   println(s"Move disc from $from to $to!") |    456   println(s"Move disc from $from to $to!") | 
|    568  |    457  | 
|    569 def hanoi(n: Int, from: Char, via: Char, to: Char) : Unit = { |    458 def hanoi(n: Int, from: Char, via: Char, to: Char) : Unit = { | 
|    573     move(from, to) |    462     move(from, to) | 
|    574     hanoi(n - 1, via, from, to) |    463     hanoi(n - 1, via, from, to) | 
|    575   } |    464   } | 
|    576 }  |    465 }  | 
|    577  |    466  | 
|    578 hanoi(40, 'A', 'B', 'C') |    467 hanoi(4, 'A', 'B', 'C') | 
|    579  |    468  | 
|    580  |    469  | 
|    581 // Tail Recursion |    470 // A Recursive Web Crawler / Email Harvester | 
|    582 //================ |    471 //=========================================== | 
|    583  |         | 
|    584  |         | 
|    585 def fact(n: Long): Long =  |         | 
|    586   if (n == 0) 1 else n * fact(n - 1) |         | 
|    587  |         | 
|    588 fact(10)              //ok |         | 
|    589 fact(10000)           // produces a stackoverflow |         | 
|    590  |         | 
|    591 def factT(n: BigInt, acc: BigInt): BigInt = |         | 
|    592   if (n == 0) acc else factT(n - 1, n * acc) |         | 
|    593  |         | 
|    594 factT(10, 1) |         | 
|    595 factT(100000, 1) |         | 
|    596  |         | 
|    597 // there is a flag for ensuring a function is tail recursive |         | 
|    598 import scala.annotation.tailrec |         | 
|    599  |         | 
|    600 @tailrec |         | 
|    601 def factT(n: BigInt, acc: BigInt): BigInt = |         | 
|    602   if (n == 0) acc else factT(n - 1, n * acc) |         | 
|    603  |         | 
|    604  |         | 
|    605  |         | 
|    606 // for tail-recursive functions the Scala compiler |         | 
|    607 // generates loop-like code, which does not need |         | 
|    608 // to allocate stack-space in each recursive |         | 
|    609 // call; Scala can do this only for tail-recursive |         | 
|    610 // functions |         | 
|    611  |         | 
|    612  |         | 
|    613 // A Web Crawler / Email Harvester |         | 
|    614 //================================= |         | 
|    615 // |    472 // | 
|    616 // the idea is to look for links using the |    473 // the idea is to look for links using the | 
|    617 // regular expression "https?://[^"]*" and for |    474 // regular expression "https?://[^"]*" and for | 
|    618 // email addresses using another regex. |    475 // email addresses using another regex. | 
|    619  |    476  | 
|    641 def get_all_URLs(page: String): Set[String] =  |    498 def get_all_URLs(page: String): Set[String] =  | 
|    642   http_pattern.findAllIn(page).map(unquote).toSet |    499   http_pattern.findAllIn(page).map(unquote).toSet | 
|    643  |    500  | 
|    644 // naive version of crawl - searches until a given depth, |    501 // naive version of crawl - searches until a given depth, | 
|    645 // visits pages potentially more than once |    502 // visits pages potentially more than once | 
|    646 def crawl(url: String, n: Int) : Set[String] = { |    503 def crawl(url: String, n: Int) : Unit = { | 
|         |    504   if (n == 0) () | 
|         |    505   else { | 
|         |    506     println(s"  Visiting: $n $url") | 
|         |    507     for (u <- get_all_URLs(get_page(url))) crawl(u, n - 1) | 
|         |    508   } | 
|         |    509 } | 
|         |    510  | 
|         |    511 // some starting URLs for the crawler | 
|         |    512 val startURL = """https://nms.kcl.ac.uk/christian.urban/""" | 
|         |    513  | 
|         |    514 crawl(startURL, 2) | 
|         |    515  | 
|         |    516  | 
|         |    517 // a primitive email harvester | 
|         |    518 def emails(url: String, n: Int) : Set[String] = { | 
|    647   if (n == 0) Set() |    519   if (n == 0) Set() | 
|    648   else { |    520   else { | 
|    649     println(s"  Visiting: $n $url") |    521     println(s"  Visiting: $n $url") | 
|    650     val page = get_page(url) |    522     val page = get_page(url) | 
|    651     val new_emails = email_pattern.findAllIn(page).toSet |    523     val new_emails = email_pattern.findAllIn(page).toSet | 
|    652     new_emails ++ (for (u <- get_all_URLs(page)) yield crawl(u, n - 1)).flatten |    524     new_emails ++ (for (u <- get_all_URLs(page)) yield emails(u, n - 1)).flatten | 
|    653   } |    525   } | 
|    654 } |    526 } | 
|    655  |    527  | 
|    656 // some starting URLs for the crawler |    528 emails(startURL, 3) | 
|    657 val startURL = """https://nms.kcl.ac.uk/christian.urban/""" |    529  | 
|    658  |    530  | 
|    659 crawl(startURL, 2) |    531 // if we want to explore the internet "deeper", then we | 
|    660  |    532 // first have to parallelise the request of webpages: | 
|    661  |    533 // | 
|    662  |    534 // scala -cp scala-parallel-collections_2.13-0.2.0.jar  | 
|    663  |    535 // import scala.collection.parallel.CollectionConverters._ | 
|    664  |    536  | 
|    665  |    537  | 
|    666  |    538  | 
|    667 // Sudoku |    539  | 
|    668 //======== |    540  | 
|    669  |    541  | 
|    670 // THE POINT OF THIS CODE IS NOT TO BE SUPER |         | 
|    671 // EFFICIENT AND FAST, just explaining exhaustive |         | 
|    672 // depth-first search |         | 
|    673  |         | 
|    674  |         | 
|    675 val game0 = """.14.6.3.. |         | 
|    676               |62...4..9 |         | 
|    677               |.8..5.6.. |         | 
|    678               |.6.2....3 |         | 
|    679               |.7..1..5. |         | 
|    680               |5....9.6. |         | 
|    681               |..6.2..3. |         | 
|    682               |1..5...92 |         | 
|    683               |..7.9.41.""".stripMargin.replaceAll("\\n", "") |         | 
|    684  |         | 
|    685 type Pos = (Int, Int) |         | 
|    686 val emptyValue = '.' |         | 
|    687 val maxValue = 9 |         | 
|    688  |         | 
|    689 val allValues = "123456789".toList |         | 
|    690 val indexes = (0 to 8).toList |         | 
|    691  |         | 
|    692  |         | 
|    693 def empty(game: String) = game.indexOf(emptyValue) |         | 
|    694 def isDone(game: String) = empty(game) == -1  |         | 
|    695 def emptyPosition(game: String) : Pos =  |         | 
|    696   (empty(game) % maxValue, empty(game) / maxValue) |         | 
|    697  |         | 
|    698  |         | 
|    699 def get_row(game: String, y: Int) = indexes.map(col => game(y * maxValue + col)) |         | 
|    700 def get_col(game: String, x: Int) = indexes.map(row => game(x + row * maxValue)) |         | 
|    701  |         | 
|    702 def get_box(game: String, pos: Pos): List[Char] = { |         | 
|    703     def base(p: Int): Int = (p / 3) * 3 |         | 
|    704     val x0 = base(pos._1) |         | 
|    705     val y0 = base(pos._2) |         | 
|    706     for (x <- (x0 until x0 + 3).toList; |         | 
|    707          y <- (y0 until y0 + 3).toList) yield game(x + y * maxValue) |         | 
|    708 }          |         | 
|    709  |         | 
|    710  |         | 
|    711 //get_row(game0, 0) |         | 
|    712 //get_row(game0, 1) |         | 
|    713 //get_box(game0, (3,1)) |         | 
|    714  |         | 
|    715 def update(game: String, pos: Int, value: Char): String =  |         | 
|    716   game.updated(pos, value) |         | 
|    717  |         | 
|    718 def toAvoid(game: String, pos: Pos): List[Char] =  |         | 
|    719   (get_col(game, pos._1) ++ get_row(game, pos._2) ++ get_box(game, pos)) |         | 
|    720  |         | 
|    721 def candidates(game: String, pos: Pos): List[Char] =  |         | 
|    722   allValues.diff(toAvoid(game, pos)) |         | 
|    723  |         | 
|    724 //candidates(game0, (0, 0)) |         | 
|    725  |         | 
|    726 def pretty(game: String): String =  |         | 
|    727   "\n" ++ (game.sliding(maxValue, maxValue).mkString("\n")) |         | 
|    728  |         | 
|    729 def search(game: String): List[String] = { |         | 
|    730   if (isDone(game)) List(game) |         | 
|    731   else  |         | 
|    732     candidates(game, emptyPosition(game)). |         | 
|    733       map(c => search(update(game, empty(game), c))).flatten |         | 
|    734 } |         | 
|    735  |         | 
|    736 // an easy game |         | 
|    737 val game1 = """23.915... |         | 
|    738               |...2..54. |         | 
|    739               |6.7...... |         | 
|    740               |..1.....9 |         | 
|    741               |89.5.3.17 |         | 
|    742               |5.....6.. |         | 
|    743               |......9.5 |         | 
|    744               |.16..7... |         | 
|    745               |...329..1""".stripMargin.replaceAll("\\n", "") |         | 
|    746  |         | 
|    747  |         | 
|    748 // a game that is in the sligtly harder category |         | 
|    749 val game2 = """8........ |         | 
|    750               |..36..... |         | 
|    751               |.7..9.2.. |         | 
|    752               |.5...7... |         | 
|    753               |....457.. |         | 
|    754               |...1...3. |         | 
|    755               |..1....68 |         | 
|    756               |..85...1. |         | 
|    757               |.9....4..""".stripMargin.replaceAll("\\n", "") |         | 
|    758  |         | 
|    759 // a game with multiple solutions |         | 
|    760 val game3 = """.8...9743 |         | 
|    761               |.5...8.1. |         | 
|    762               |.1....... |         | 
|    763               |8....5... |         | 
|    764               |...8.4... |         | 
|    765               |...3....6 |         | 
|    766               |.......7. |         | 
|    767               |.3.5...8. |         | 
|    768               |9724...5.""".stripMargin.replaceAll("\\n", "") |         | 
|    769  |         | 
|    770  |         | 
|    771 search(game0).map(pretty) |         | 
|    772 search(game1).map(pretty) |         | 
|    773  |         | 
|    774 // for measuring time |         | 
|    775 def time_needed[T](i: Int, code: => T) = { |         | 
|    776   val start = System.nanoTime() |         | 
|    777   for (j <- 1 to i) code |         | 
|    778   val end = System.nanoTime() |         | 
|    779   s"${(end - start) / i / 1.0e9} secs" |         | 
|    780 } |         | 
|    781  |         | 
|    782 search(game2).map(pretty) |         | 
|    783 search(game3).distinct.length |         | 
|    784 time_needed(3, search(game2)) |         | 
|    785 time_needed(3, search(game3)) |         | 
|    786  |         | 
|    787  |         | 
|    788  |         | 
|    789  |         | 
|    790  |         | 
|    791  |         |