37 for (i <- (0 until lst.length).toList) yield square(lst(i))  | 
    37 for (i <- (0 until lst.length).toList) yield square(lst(i))  | 
    38   | 
    38   | 
    39 // this is just so prone to off-by-one errors;  | 
    39 // this is just so prone to off-by-one errors;  | 
    40 // write instead  | 
    40 // write instead  | 
    41   | 
    41   | 
    42 for (e <- lst) yield square(e)  | 
    42 for (e <- lst; if (e % 2) == 0; if (e != 4)) yield square(e)  | 
    43   | 
    43   | 
    44   | 
    44   | 
    45 //this works for sets as well  | 
    45 //this works for sets as well  | 
    46 val st = Set(1, 2, 3, 4, 5, 6, 7, 8, 9)  | 
    46 val st = Set(1, 2, 3, 4, 5, 6, 7, 8, 9)  | 
    47   | 
    47   | 
    69   | 
    69   | 
    70   | 
    70   | 
    71   | 
    71   | 
    72 // know when to use yield and when not:  | 
    72 // know when to use yield and when not:  | 
    73   | 
    73   | 
    74 for (e <- Set(1, 2, 3, 4, 5, 6, 7, 8, 9); if e < 5) yield square(e)  | 
    74 val test =   | 
         | 
    75  for (e <- Set(1, 2, 3, 4, 5, 6, 7, 8, 9); if e < 5) yield square(e)  | 
         | 
    76   | 
    75   | 
    77   | 
    76   | 
    78   | 
    77 // Option type  | 
    79 // Option type  | 
    78 //=============  | 
    80 //=============  | 
    79   | 
    81   | 
    81 //in Scala you use Option  | 
    83 //in Scala you use Option  | 
    82 //   - if the value is present, you use Some(value)  | 
    84 //   - if the value is present, you use Some(value)  | 
    83 //   - if no value is present, you use None  | 
    85 //   - if no value is present, you use None  | 
    84   | 
    86   | 
    85   | 
    87   | 
    86 List(7,2,3,4,5,6).find(_ < 4)  | 
    88 List(7,24,3,4,5,6).find(_ < 4)  | 
    87 List(5,6,7,8,9).find(_ < 4)  | 
    89 List(5,6,7,8,9).find(_ < 4)  | 
    88   | 
    90   | 
         | 
    91 List(7,2,3,4,5,6).filter(_ < 4)  | 
    89   | 
    92   | 
    90 // some operations on Option's  | 
    93 // some operations on Option's  | 
    91   | 
    94   | 
    92 val lst = List(None, Some(1), Some(2), None, Some(3))  | 
    95 val lst = List(None, Some(1), Some(2), None, Some(3))  | 
    93   | 
    96   | 
    94 lst.flatten  | 
    97 lst.flatten  | 
    95   | 
    98   | 
    96 Some(1).get  | 
    99 Some(10).get  | 
         | 
   100 None.get  | 
    97   | 
   101   | 
    98 Some(1).isDefined  | 
   102 Some(1).isDefined  | 
    99 None.isDefined  | 
   103 None.isDefined  | 
   100   | 
   104   | 
   101 val ps = List((3, 0), (3, 2), (4, 2), (2, 0), (1, 0), (1, 1))  | 
   105 val ps = List((3, 0), (3, 2), (4, 2), (2, 0), (1, 0), (1, 1))  | 
   165 // code could potentially throw a NullPointerException.  | 
   170 // code could potentially throw a NullPointerException.  | 
   166   | 
   171   | 
   167   | 
   172   | 
   168 // even Scala is not immune to problems like this:  | 
   173 // even Scala is not immune to problems like this:  | 
   169   | 
   174   | 
   170 List(5,6,7,8,9).indexOf(7)  | 
   175 List(5,6,7,8,9).indexOf(42)  | 
   171   | 
   176   | 
   172   | 
   177   | 
         | 
   178 // ... how are we supposed to know that this returns -1  | 
   173   | 
   179   | 
   174   | 
   180   | 
   175 // Higher-Order Functions  | 
   181 // Higher-Order Functions  | 
   176 //========================  | 
   182 //========================  | 
   177   | 
   183   | 
   180 val lst = (1 to 10).toList  | 
   186 val lst = (1 to 10).toList  | 
   181   | 
   187   | 
   182 def even(x: Int) : Boolean = x % 2 == 0  | 
   188 def even(x: Int) : Boolean = x % 2 == 0  | 
   183 def odd(x: Int) : Boolean = x % 2 == 1  | 
   189 def odd(x: Int) : Boolean = x % 2 == 1  | 
   184   | 
   190   | 
   185 lst.filter(x => even(x))  | 
   191 lst.filter(x => even(x) && odd(x))  | 
   186 lst.filter(even(_))  | 
   192 lst.filter(even(_))  | 
   187 lst.filter(even)  | 
   193 lst.filter(odd && even)  | 
   188   | 
   194   | 
   189 lst.find(_ > 8)  | 
   195 lst.find(_ > 8)  | 
   190   | 
   196   | 
   191 // map applies a function to each element of a list  | 
   197 // map applies a function to each element of a list  | 
   192   | 
   198   | 
   193 def square(x: Int): Int = x * x  | 
   199 def square(x: Int): Int = x * x  | 
   194   | 
   200   | 
         | 
   201 val lst = (1 to 10).toList  | 
   195 lst.map(square)  | 
   202 lst.map(square)  | 
   196   | 
   203   | 
   197 lst.map(square).filter(_ > 4)  | 
   204 lst.map(square).filter(_ > 4)  | 
   198   | 
   205   | 
   199 lst.map(square).filter(_ > 4).map(square)  | 
   206 lst.map(square).filter(_ > 4).map(square)  | 
   200   | 
   207   | 
   201 // map works for most collection types, including sets  | 
   208 // map works for most collection types, including sets  | 
   202 Set(1, 3, 6).map(square)  | 
   209 Set(1, 3, 6).map(square).filter(_ > 4)  | 
   203   | 
   210   | 
   204   | 
   211   | 
   205 // Why could functions as arguments be useful?  | 
   212 val l = List((1, 3),(2, 4),(4, 1),(6, 2))  | 
         | 
   213   | 
         | 
   214 l.map(square(_._1))  | 
         | 
   215   | 
         | 
   216   | 
         | 
   217 // Why are functions as arguments useful?  | 
   206 //  | 
   218 //  | 
   207 // Consider the sum between a and b:  | 
   219 // Consider the sum between a and b:  | 
   208   | 
   220   | 
   209 def sumInts(a: Int, b: Int) : Int =   | 
   221 def sumInts(a: Int, b: Int) : Int =   | 
   210   if (a > b) 0 else a + sumInts(a + 1, b)  | 
   222   if (a > b) 0 else a + sumInts(a + 1, b)  | 
   211   | 
   223   | 
   212   | 
   224   | 
   213 sumInt(10, 16)  | 
   225 sumInts(10, 16)  | 
   214   | 
   226   | 
   215 // sum squares  | 
   227 // sum squares  | 
   216 def square(n: Int) : Int = n * n  | 
   228 def square(n: Int) : Int = n * n  | 
   217   | 
   229   | 
   218 def sumSquares(a: Int, b: Int) : Int =   | 
   230 def sumSquares(a: Int, b: Int) : Int =   | 
   230   | 
   242   | 
   231 sumFacts(2, 6)  | 
   243 sumFacts(2, 6)  | 
   232   | 
   244   | 
   233   | 
   245   | 
   234   | 
   246   | 
   235 // You can see the pattern....can we simplify out work?  | 
   247 // You can see the pattern....can we simplify our work?  | 
   236 // The type of functions from ints to ints: Int => Int  | 
   248 // The type of functions from ints to ints: Int => Int  | 
   237   | 
   249   | 
   238 def sum(f: Int => Int, a: Int, b: Int) : Int = { | 
   250 def sum(f: Int => Int, a: Int, b: Int) : Int = { | 
   239   if (a > b) 0   | 
   251   if (a > b) 0   | 
   240   else f(a) + sum(f, a + 1, b)  | 
   252   else f(a) + sum(f, a + 1, b)  | 
   247 // What should we do for sumInts?  | 
   259 // What should we do for sumInts?  | 
   248   | 
   260   | 
   249 def id(n: Int) : Int = n  | 
   261 def id(n: Int) : Int = n  | 
   250 def sumInts(a: Int, b: Int) : Int = sum(id, a, b)  | 
   262 def sumInts(a: Int, b: Int) : Int = sum(id, a, b)  | 
   251   | 
   263   | 
         | 
   264 sumInts(10, 12)  | 
   252   | 
   265   | 
   253   | 
   266   | 
   254 // Anonymous Functions: You can also write:  | 
   267 // Anonymous Functions: You can also write:  | 
   255   | 
   268   | 
   256 def sumCubes(a: Int, b: Int) : Int =   sum(x => x * x * x, a, b)  | 
   269 def sumCubes(a: Int, b: Int) : Int =   sum(x => x * x * x, a, b)  | 
   266   | 
   279   | 
   267   | 
   280   | 
   268 // an aside: partial application  | 
   281 // an aside: partial application  | 
   269   | 
   282   | 
   270 def add(a: Int)(b: Int) : Int = a + b  | 
   283 def add(a: Int)(b: Int) : Int = a + b  | 
         | 
   284 def add_abc(a: Int)(b: Int)(c: Int) : Int = a + b + c  | 
         | 
   285   | 
         | 
   286 val add2 : Int => Int = add(2)  | 
         | 
   287 add2(5)  | 
         | 
   288   | 
         | 
   289 val add2_bc : Int => Int => Int = add_abc(2)   | 
         | 
   290 val add2_9_c : Int => Int = add2_bc(9)   | 
         | 
   291   | 
         | 
   292 add2_9_c(10)  | 
   271   | 
   293   | 
   272 sum(add(2), 0, 2)  | 
   294 sum(add(2), 0, 2)  | 
   273 sum(add(10), 0, 2)  | 
   295 sum(add(10), 0, 2)  | 
   274   | 
   296   | 
   275 def add2(a: Int, b: Int) : Int = a + b  | 
         | 
   276 sum(x => add2(2, x), 0, 2)  | 
         | 
   277 sum(x => add2(10, x), 0, 2)  | 
         | 
   278   | 
   297   | 
   279 // Function Composition  | 
   298 // Function Composition  | 
   280 //======================  | 
   299 //======================  | 
   281   | 
   300   | 
   282 // How could Higher-Order Functions and Options be helpful?  | 
   301 // How can be Higher-Order Functions and Options be helpful?  | 
   283   | 
   302   | 
   284 def add_footer(msg: String) : String = msg ++ " - Sent from iOS"  | 
   303 def add_footer(msg: String) : String = msg ++ " - Sent from iOS"  | 
   285   | 
   304   | 
   286 def valid_msg(msg: String) : Boolean = msg.size <= 140  | 
   305 def valid_msg(msg: String) : Boolean = msg.size <= 140  | 
   287   | 
   306   | 
   288 def duplicate(s: String) : String = s ++ s  | 
   307 def duplicate(s: String) : String = s ++ s  | 
   289   | 
   308   | 
   290 // they compose nicely  | 
   309 // they compose very nicely, e.g  | 
         | 
   310   | 
   291 valid_msg(add_footer("Hello World")) | 
   311 valid_msg(add_footer("Hello World")) | 
   292 valid_msg(duplicate(add_footer("Hello World"))) | 
   312 valid_msg(duplicate(duplicate(add_footer("Helloooooooooooooooooo World")))) | 
   293   | 
   313   | 
   294   | 
   314 // but not all functions do  | 
   295 // first_word: let's first do it the ugly Java way using null:  | 
   315 // first_word: let's first do it the ugly Java way using null:  | 
   296   | 
   316   | 
   297 def first_word(msg: String) : String = { | 
   317 def first_word(msg: String) : String = { | 
   298   val words = msg.split(" ") | 
   318   val words = msg.split(" ") | 
   299   if (words(0) != "") words(0) else null  | 
   319   if (words(0) != "") words(0) else null  | 
   304   | 
   324   | 
   305 def extended_duplicate(s: String) : String =   | 
   325 def extended_duplicate(s: String) : String =   | 
   306   if (s != null) s ++ s else null  | 
   326   if (s != null) s ++ s else null  | 
   307   | 
   327   | 
   308 extended_duplicate(first_word("")) | 
   328 extended_duplicate(first_word("")) | 
         | 
   329   | 
         | 
   330 // but this is against the rules of the game: we do not want  | 
         | 
   331 // to change duplicate, because first_word might return null  | 
   309   | 
   332   | 
   310   | 
   333   | 
   311 // Avoid always null!  | 
   334 // Avoid always null!  | 
   312 def better_first_word(msg: String) : Option[String] = { | 
   335 def better_first_word(msg: String) : Option[String] = { | 
   313   val words = msg.split(" ") | 
   336   val words = msg.split(" ") | 
   314   if (words(0) != "") Some(words(0)) else None  | 
   337   if (words(0) != "") Some(words(0)) else None  | 
   315 }  | 
   338 }  | 
   316   | 
   339   | 
   317 better_first_word("Hello World").map(duplicate) | 
   340 better_first_word("Hello World").map(duplicate) | 
   318 better_first_word("Hello World").map(duplicate).map(duplicate).map(valid_msg) | 
   341   | 
         | 
   342 better_first_word("Hello World").map(duplicate) | 
         | 
   343 better_first_word("").map(duplicate).map(duplicate).map(valid_msg) | 
   319   | 
   344   | 
   320 better_first_word("").map(duplicate) | 
   345 better_first_word("").map(duplicate) | 
   321 better_first_word("").map(duplicate).map(valid_msg) | 
   346 better_first_word("").map(duplicate).map(valid_msg) | 
   322   | 
         | 
   323   | 
         | 
   324   | 
         | 
   325   | 
         | 
   326   | 
         | 
   327   | 
         | 
   328 // Implicits (Cool Feature)  | 
         | 
   329 //=========================  | 
         | 
   330 //  | 
         | 
   331 // For example adding your own methods to Strings:  | 
         | 
   332 // Imagine you want to increment strings, like  | 
         | 
   333 //  | 
         | 
   334 //     "HAL".increment  | 
         | 
   335 //  | 
         | 
   336 // you can avoid ugly fudges, like a MyString, by  | 
         | 
   337 // using implicit conversions.  | 
         | 
   338   | 
         | 
   339   | 
         | 
   340 implicit class MyString(s: String) { | 
         | 
   341   def increment = for (c <- s) yield (c + 1).toChar   | 
         | 
   342 }  | 
         | 
   343   | 
         | 
   344 "HAL".increment  | 
         | 
   345   | 
         | 
   346   | 
         | 
   347   | 
         | 
   348 // No returns in Scala  | 
         | 
   349 //====================  | 
         | 
   350   | 
         | 
   351 // You should not use "return" in Scala:  | 
         | 
   352 //  | 
         | 
   353 // A return expression, when evaluated, abandons the   | 
         | 
   354 // current computation and returns to the caller of the   | 
         | 
   355 // function in which return appears."  | 
         | 
   356   | 
         | 
   357 def sq1(x: Int): Int = x * x  | 
         | 
   358 def sq2(x: Int): Int = return x * x  | 
         | 
   359   | 
         | 
   360 def sumq(ls: List[Int]): Int = { | 
         | 
   361   ls.map(sq1).sum[Int]  | 
         | 
   362 }  | 
         | 
   363   | 
         | 
   364 sumq(List(1, 2, 3, 4))  | 
         | 
   365   | 
         | 
   366   | 
         | 
   367   | 
         | 
   368 def sumq(ls: List[Int]): Int = { | 
         | 
   369   val sqs : List[Int] = for (x <- ls) yield (return x * x)  | 
         | 
   370   sqs.sum  | 
         | 
   371 }  | 
         | 
   372   | 
         | 
   373   | 
         | 
   374   | 
   347   | 
   375   | 
   348   | 
   376 // Pattern Matching  | 
   349 // Pattern Matching  | 
   377 //==================  | 
   350 //==================  | 
   378   | 
   351   | 
   447   case Green() => true  | 
   420   case Green() => true  | 
   448   case Blue()  => false   | 
   421   case Blue()  => false   | 
   449 }  | 
   422 }  | 
   450   | 
   423   | 
   451   | 
   424   | 
   452 // actually this can be written with "object"  | 
   425 // actually colors can be written with "object",  | 
         | 
   426 // because they do not take any arguments  | 
   453   | 
   427   | 
   454   | 
   428   | 
   455 // another example  | 
   429 // another example  | 
   456 //=================  | 
   430 //=================  | 
         | 
   431   | 
         | 
   432 // Once upon a time, in a complete fictional country there were persons...  | 
   457   | 
   433   | 
   458 abstract class Person  | 
   434 abstract class Person  | 
   459 case class King() extends Person  | 
   435 case class King() extends Person  | 
   460 case class Peer(deg: String, terr: String, succ: Int) extends Person  | 
   436 case class Peer(deg: String, terr: String, succ: Int) extends Person  | 
   461 case class Knight(name: String) extends Person  | 
   437 case class Knight(name: String) extends Person  | 
   506 val A = (1 to 1000).toSet  | 
   481 val A = (1 to 1000).toSet  | 
   507 val B = (1 to 1000 by 4).toSet  | 
   482 val B = (1 to 1000 by 4).toSet  | 
   508   | 
   483   | 
   509 count_intersection(A, B)  | 
   484 count_intersection(A, B)  | 
   510   | 
   485   | 
   511 // but do not try to add .par to the for-loop above  | 
   486 // but do not try to add .par to the for-loop above,  | 
         | 
   487 // otherwise you will be caught in race-condition hell.  | 
   512   | 
   488   | 
   513   | 
   489   | 
   514 //propper parallel version  | 
   490 //propper parallel version  | 
   515 def count_intersection2(A: Set[Int], B: Set[Int]) : Int =   | 
   491 def count_intersection2(A: Set[Int], B: Set[Int]) : Int =   | 
   516   A.par.count(x => B contains x)  | 
   492   A.par.count(x => B contains x)  | 
   531   | 
   507   | 
   532 time_needed(10, count_intersection(A, B))  | 
   508 time_needed(10, count_intersection(A, B))  | 
   533 time_needed(10, count_intersection2(A, B))  | 
   509 time_needed(10, count_intersection2(A, B))  | 
   534   | 
   510   | 
   535   | 
   511   | 
         | 
   512 // Implicits (Cool Feature)  | 
         | 
   513 //=========================  | 
         | 
   514 //  | 
         | 
   515 // For example adding your own methods to Strings:  | 
         | 
   516 // Imagine you want to increment strings, like  | 
         | 
   517 //  | 
         | 
   518 //     "HAL".increment  | 
         | 
   519 //  | 
         | 
   520 // you can avoid ugly fudges, like a MyString, by  | 
         | 
   521 // using implicit conversions.  | 
         | 
   522   | 
         | 
   523   | 
         | 
   524 implicit class MyString(s: String) { | 
         | 
   525   def increment = for (c <- s) yield (c + 1).toChar   | 
         | 
   526 }  | 
         | 
   527   | 
         | 
   528 "HAL".increment  | 
         | 
   529   | 
         | 
   530   | 
         | 
   531   | 
         | 
   532 // No returns in Scala  | 
         | 
   533 //====================  | 
         | 
   534   | 
         | 
   535 // You should not use "return" in Scala:  | 
         | 
   536 //  | 
         | 
   537 // A return expression, when evaluated, abandons the   | 
         | 
   538 // current computation and returns to the caller of the   | 
         | 
   539 // function in which return appears."  | 
         | 
   540   | 
         | 
   541 def sq1(x: Int): Int = x * x  | 
         | 
   542 def sq2(x: Int): Int = return x * x  | 
         | 
   543   | 
         | 
   544 def sumq(ls: List[Int]): Int = { | 
         | 
   545   ls.map(sq1).sum[Int]  | 
         | 
   546 }  | 
         | 
   547   | 
         | 
   548 sumq(List(1, 2, 3, 4))  | 
         | 
   549   | 
         | 
   550   | 
         | 
   551   | 
         | 
   552 def sumq(ls: List[Int]): Int = { | 
         | 
   553   val sqs : List[Int] = for (x <- ls) yield (return x * x)  | 
         | 
   554   sqs.sum  | 
         | 
   555 }  | 
         | 
   556   | 
         | 
   557   | 
         | 
   558   | 
         | 
   559   | 
   536 // Type abbreviations  | 
   560 // Type abbreviations  | 
   537 //====================  | 
   561 //====================  | 
   538   | 
   562   | 
   539 // some syntactic convenience  | 
   563 // some syntactic convenience  | 
   540   | 
   564   | 
   570 val indexes = (0 to 8).toList  | 
   594 val indexes = (0 to 8).toList  | 
   571   | 
   595   | 
   572   | 
   596   | 
   573 def empty(game: String) = game.indexOf(EmptyValue)  | 
   597 def empty(game: String) = game.indexOf(EmptyValue)  | 
   574 def isDone(game: String) = empty(game) == -1   | 
   598 def isDone(game: String) = empty(game) == -1   | 
   575 def emptyPosition(game: String) = (empty(game) % MaxValue, empty(game) / MaxValue)  | 
   599 def emptyPosition(game: String) =   | 
   576   | 
   600   (empty(game) % MaxValue, empty(game) / MaxValue)  | 
   577   | 
   601   | 
   578 def get_row(game: String, y: Int) = indexes.map(col => game(y * MaxValue + col))  | 
   602   | 
   579 def get_col(game: String, x: Int) = indexes.map(row => game(x + row * MaxValue))  | 
   603 def get_row(game: String, y: Int) =   | 
         | 
   604   indexes.map(col => game(y * MaxValue + col))  | 
         | 
   605 def get_col(game: String, x: Int) =   | 
         | 
   606   indexes.map(row => game(x + row * MaxValue))  | 
   580   | 
   607   | 
   581 get_row(game0, 3)  | 
   608 get_row(game0, 3)  | 
   582 get_col(game0, 0)  | 
   609 get_col(game0, 0)  | 
   583   | 
   610   | 
   584 def get_box(game: String, pos: Pos): List[Char] = { | 
   611 def get_box(game: String, pos: Pos): List[Char] = { | 
   592 get_box(game0, (0, 0))  | 
   619 get_box(game0, (0, 0))  | 
   593 get_box(game0, (1, 1))  | 
   620 get_box(game0, (1, 1))  | 
   594 get_box(game0, (2, 1))  | 
   621 get_box(game0, (2, 1))  | 
   595   | 
   622   | 
   596 // this is not mutable!!  | 
   623 // this is not mutable!!  | 
   597 def update(game: String, pos: Int, value: Char): String = game.updated(pos, value)  | 
   624 def update(game: String, pos: Int, value: Char): String =   | 
         | 
   625   game.updated(pos, value)  | 
   598   | 
   626   | 
   599 def toAvoid(game: String, pos: Pos): List[Char] =   | 
   627 def toAvoid(game: String, pos: Pos): List[Char] =   | 
   600   (get_col(game, pos._1) ++ get_row(game, pos._2) ++ get_box(game, pos))  | 
   628   (get_col(game, pos._1) ++ get_row(game, pos._2) ++ get_box(game, pos))  | 
   601   | 
   629   | 
   602 def candidates(game: String, pos: Pos): List[Char] = allValues.diff(toAvoid(game,pos))  | 
   630 def candidates(game: String, pos: Pos): List[Char] =   | 
         | 
   631   allValues.diff(toAvoid(game,pos))  | 
   603   | 
   632   | 
   604 //candidates(game0, (0,0))  | 
   633 //candidates(game0, (0,0))  | 
   605   | 
   634   | 
   606 def pretty(game: String): String =   | 
   635 def pretty(game: String): String =   | 
   607   "\n" + (game sliding (MaxValue, MaxValue) mkString "\n")  | 
   636   "\n" + (game sliding (MaxValue, MaxValue) mkString "\n")  | 
   608   | 
   637   | 
   609 def search(game: String): List[String] = { | 
   638 def search(game: String): List[String] = { | 
   610   if (isDone(game)) List(game)  | 
   639   if (isDone(game)) List(game)  | 
   611   else { | 
   640   else { | 
   612     val cs = candidates(game, emptyPosition(game))  | 
   641     val cs = candidates(game, emptyPosition(game))  | 
   613     cs.map(c => search(update(game, empty(game), c))).toList.flatten  | 
   642     cs.par.map(c => search(update(game, empty(game), c))).toList.flatten  | 
   614   }  | 
   643   }  | 
   615 }  | 
   644 }  | 
   616   | 
   645   | 
   617 search(game0).map(pretty)  | 
   646 search(game0).map(pretty)  | 
   618   | 
   647   |