//############################################################################ // Programmation IV - 2002 - Week 05 //############################################################################ object M0 { def partition[a](xs: List[a], pred: a => Boolean): Tuple2[List[a], List[a]] = { if (xs.isEmpty) (List(),List()) else { val tailPartition = partition(xs.tail, pred); if (pred(xs.head)) (xs.head :: tailPartition._1, tailPartition._2) else (tailPartition._1, xs.head :: tailPartition._2) } } def quicksort[a] (less : (a,a) => Boolean) (xs : List[a]) : List[a] = { if (xs.isEmpty) xs else { val pivot = xs.head; val sub = partition(xs.tail, { elem : a => less(elem, pivot) }); quicksort(less)(sub._1) ::: List(pivot) ::: quicksort(less)(sub._2) } } def test = { Console.println(partition[Int](List(1,2,3,4,5,6,7,8), (x => x < 0))); Console.println(partition[Int](List(1,2,3,4,5,6,7,8), (x => x < 5))); Console.println(partition[Int](List(1,2,3,4,5,6,7,8), (x => x < 9))); Console.println; Console.println(partition[Int](List(8,7,6,5,4,3,2,1), (x => x < 0))); Console.println(partition[Int](List(8,7,6,5,4,3,2,1), (x => x < 5))); Console.println(partition[Int](List(8,7,6,5,4,3,2,1), (x => x < 9))); Console.println; Console.println(partition[Int](List(7,2,1,5,4,3,8,6), (x => x < 0))); Console.println(partition[Int](List(7,2,1,5,4,3,8,6), (x => x < 5))); Console.println(partition[Int](List(7,2,1,5,4,3,8,6), (x => x < 9))); Console.println; Console.println(quicksort[Int]((x,y) => x < y)(List(7,2,1,5,4,3,8,6))); Console.println; } } //############################################################################ object M1 { def partition[a](xs: List[a], pred: a => Boolean): Tuple2[List[a], List[a]] = { xs.foldRight[Tuple2[List[a], List[a]]]((List(), List())) { (x, p) => if (pred (x)) (x :: p._1, p._2) else (p._1, x :: p._2) } } def quicksort[a] (less : (a,a) => Boolean) (xs : List[a]) : List[a] = { if (xs.isEmpty) xs else { val pivot = xs.head; val sub = partition(xs.tail, (elem : a) => less(elem, pivot)); quicksort(less)(sub._1) ::: List(pivot) ::: quicksort(less)(sub._2) } } def test = { Console.println(partition[Int](List(1,2,3,4,5,6,7,8), (x => x < 0))); Console.println(partition[Int](List(1,2,3,4,5,6,7,8), (x => x < 5))); Console.println(partition[Int](List(1,2,3,4,5,6,7,8), (x => x < 9))); Console.println; Console.println(partition[Int](List(8,7,6,5,4,3,2,1), (x => x < 0))); Console.println(partition[Int](List(8,7,6,5,4,3,2,1), (x => x < 5))); Console.println(partition[Int](List(8,7,6,5,4,3,2,1), (x => x < 9))); Console.println; Console.println(partition[Int](List(7,2,1,5,4,3,8,6), (x => x < 0))); Console.println(partition[Int](List(7,2,1,5,4,3,8,6), (x => x < 5))); Console.println(partition[Int](List(7,2,1,5,4,3,8,6), (x => x < 9))); Console.println; Console.println(quicksort[Int]((x,y) => x < y)(List(7,2,1,5,4,3,8,6))); Console.println; } } //############################################################################ object M2 { def powerset[a] (s: List[a]): List[List[a]] = { if (s.isEmpty) List(List()) else { val x = s.head; val withoutX = powerset(s.tail); withoutX ::: withoutX.map { s1 : List[a] => x::s1 } } } def test = { Console.println(powerset(List())); Console.println(powerset(List(1))); Console.println(powerset(List(1,2))); Console.println(powerset(List(1,2,3))); Console.println(powerset(List(1,2,3,4))); Console.println; } } //############################################################################ object M3 { def abs(x: Int) = if (x < 0) 0 - x else x; def range(lo: Int, hi: Int): List[Int] = if (lo > hi) List() else lo :: range(lo + 1, hi); type Placement = List[(Int, Int)]; def queens(n: Int): List[Placement] = { def placeQueens(row: Int): List[Placement] = { if (row == 0) List(List()) else { def isSafe(column: Int, placement: Placement): Boolean = placement forall { pos => (pos._2 != column && abs(pos._2 - column) != row - pos._1) } def adjoinRow(placement: Placement): List[Placement] = range(1, n) .filter (column => isSafe(column, placement)) .map (column => (row, column) :: placement); placeQueens(row - 1) flatMap adjoinRow } } placeQueens(n) } def test: Unit = { Console.println("queens(1) = " + queens(1)); Console.println("queens(2) = " + queens(2)); Console.println("queens(3) = " + queens(3)); Console.println("queens(4) = " + queens(4)); Console.println; } } //############################################################################ object M4 { def abs(x: Int) = if (x < 0) 0 - x else x; def range(lo: Int, hi: Int): List[Int] = if (lo > hi) List() else lo :: range(lo + 1, hi); type Placement = List[Int]; def queens(n: Int): List[Placement] = { val columns = range(1, n); def placeQueens(row: Int): List[Placement] = { if (row == 0) List(List()) else { def isSafe(col: Int, p: Placement, delta: Int): Boolean = (p.isEmpty || (col != p.head && abs(col - p.head) != delta && isSafe(col, p.tail, delta + 1))); for ( placement <- placeQueens(row - 1); col <- columns; if isSafe(col, placement, 1) ) yield { col :: placement } } } placeQueens(n); } def test: Unit = { Console.println("queens(1) = " + queens(1)); Console.println("queens(2) = " + queens(2)); Console.println("queens(3) = " + queens(3)); Console.println("queens(4) = " + queens(4)); Console.println; } } //############################################################################ object Test { def main(args: Array[String]): Unit = { M0.test; M1.test; M2.test; M3.test; M4.test; () } } //############################################################################