/**
 * Exercise 10.1.1 Write the function
 *
 * def isSafe(col: Int, queens: List[Int], delta: Int): Boolean
 *
 * which tests whether a queen in the given column col is safe with respect to
 * the queens already placed. Here, delta is the difference between the row of
 * the queen to be placed and the row of the first queen in the list.
 */

def queens(n: Int): List[List[Int]] = {
  def placeQueens(k: Int): List[List[Int]] =
    if (k == 0) List(List())
    else
      for {queens < - placeQueens(k - 1)
           column <- List.range(1, n + 1)
        if isSafe(column, queens, 1) } yield column :: queens
    placeQueens(n)
}

def isSafe(col: Int, queens: List[Int], delta: Int): Boolean = queens match {
  case Nil    => true
  case h :: t => !(h == col) && abs(h - col) && ifSafe(col, t, delta + 1)
}

 

 

/**
 * Exercise 10.3.1 Define the following function in terms of for.
 *
 * def flatten[A](xss: List[List[A]]): List[A] =
 *   (xss :\ (Nil: List[A])) ((xs, ys) => xs ::: ys)
 */
def flatten[A](xss: List[List[A]]): List[A] =
  for (x < - xss) yield x

 

 

/**
 * Exercise 10.3.2 Translate
 *
 * for (b < - books; a <- b.authors if a startsWith "Bird") yield b.title
 * for (b <- books if (b.title indexOf "Program") >= 0) yield b.title
 *
 * to higher-order functions.
 */

/*
 supose class Book(title: String, authors: String*)
*/

def filterBirds(books: List[Book]): List[String] = books match {
  case Nil    => Nil
  case h :: t =>
    if (h.authors startsWith "Bird")
      h.title :: filterBirds(t)
    else
      filterBirds(t)
}

def filterProgramBooks(books: List[Book]): List[String] = books match {
  case Nil    => Nil
  case h :: t =>
    if ((h.title indexOf "Program") >= 0)
      h.title :: filterProgramBooks(t)
    else
      filterProgramBooks(t)
}