Assignment 6 (work in progress).
[Scala.git] / Assignment_05 / src / main / scala / Main.scala
index a6886bc..5b175fd 100644 (file)
@@ -10,12 +10,81 @@ object Main {
   def lString(l: List[String]): Int = l.foldLeft(0)((acc, s) => acc + s.length())
   def longest(l: List[String]): (Int, String) = l.foldLeft(0, ""){ case (curr@(len, longestStr), str) => if (str.length() > len) (str.length(), str) else curr }
   def isPresent[T](l: List[T], e: T): Boolean = l.foldLeft(false)((acc, e2) => acc || e == e2)
-  def flattenList[T](l: List[T]): List[T] = l.foldRight (List.empty[T]) ((e: T, acc: List[T]) =>
-    e match {
-      case l: List[T] => flattenList(l) ++ acc
-      case _ => e :: acc
+  def flattenList(l: List[Any]): List[Any] = l.foldRight (List.empty[Any]) {
+    case (e: List[Any], acc) => flattenList(e) ++ acc
+    case (e, acc) => e:: acc
+  }
+
+  // Question 3: Tuples.
+  def primeSum(max: Int): List[(Int, Int)] =
+    for {
+      i <- (1 to max).toList
+      j <- (1 to max).toList
+      if isPrime(i + j)
+    } yield (i, j)
+
+  def isPrime(i: Int): Boolean =
+    if (i <= 1 || i % 2 == 0)
+      false
+    else
+      !(3 to Math.sqrt(i).toInt).exists(i % _ == 0)
+
+  // a)
+  def primeSumUnique1(max: Int): List[(Int, Int)] = {
+    def loop(l: List[(Int, Int)]): List[(Int, Int)] = l match {
+      case Nil => Nil
+      case (t@(a, b)) :: rest => if (a > b) t :: loop(rest) else loop(rest)
+    }
+    loop(primeSum(max))
+  }
+
+  // b)
+  def primeSumUnique2(max: Int): List[(Int, Int)] =
+    primeSum(max).foldLeft(List[(Int, Int)]())((acc, t) => if (t._1 > t._2) t :: acc else acc)
+
+  // Question 4.
+  val cities = List("Paris", "London", "Berlin", "Lausanne")
+  val relatives = List("Grandma", "Grandpa", "Aunt Lottie", "Dad")
+  val travellers = List("Pierre-Andre", "Rachel")
+
+  def postcards : List[String] =
+    for {
+      city <- cities
+      relative <- relatives
+      traveller <- travellers
+      if relative.charAt(0).toLower == 'g'
+    } yield s"Dear ${relative}, Wish you were here in ${city}! Love, ${traveller}"
+
+  // Question 5.
+  def queens(n: Int): List[List[(Int, Int)]] = {
+    def placeQueens(k: Int): List[List[(Int, Int)]] =
+      if (k == 0)
+        List(List())
+      else
+        for {
+          queens <- placeQueens(k - 1)
+          column <- 1 to n
+          queen = (k, column)
+          if isSafe(queen, queens)
+        } yield queen :: queens
+    placeQueens(n)
+  }
+
+  def isSafe(queen: (Int, Int), queens: List[(Int, Int)]) =
+    queens forall (q => !inCheck(queen, q))
+
+  def inCheck(q1: (Int, Int), q2: (Int, Int)) =
+    q1._1 == q2._1 || // Same row.
+    q1._2 == q2._2 || // Same column.
+    (q1._1 - q2._1).abs == (q1._2 - q2._2).abs // On diagonal.
+
+  def printChessBoard(boards: List[List[(Int, Int)]]) =
+    (boards zipWithIndex).foldLeft("") { case (acc, (board, index)) =>
+      acc + s"Solution ${index + 1}:\n" + {
+        val l = board.length
+        (for {r <- 1 to l; c <- 1 to l} yield (if (c == 1) "|" else "") + (if (board contains(r, c)) "\u265b" else "_") + "|" + (if (c == l) "\n" else "")) reduce (_ + _)
+      }
     }
-  )
 
   def main(args: Array[String]): Unit = {
     println("Question 1")
@@ -23,7 +92,7 @@ object Main {
     println(s"b) ${dup("foo", 5)}")
     println(s"c) ${dot(List(1, 2, 3), List(2, 4, 3))}")
 
-    println("Question 2")
+    println("\nQuestion 2")
     println("a)")
     println(s"${areTrue(List(true, true, false))}")
     println(s"${areTrue(List(true, true, true))}")
@@ -37,5 +106,15 @@ object Main {
     println("e)")
     val l = List(List(1, 1), 2, List(3, List(5, 8)));
     println(s"flattenList($l): ${flattenList(l)}")
+
+    println("\nQuestion 3")
+    println(s"a) ${primeSumUnique1(7)}")
+    println(s"b) ${primeSumUnique2(7)}")
+
+    println("\nQuestion 4")
+    postcards.foreach(p => println(p))
+
+    println("\nQuestion 5")
+    println(printChessBoard(queens(4)))
   }
 }