|         |      1 // Main Part 4 about finding Knight's tours | 
|         |      2 //========================================== | 
|         |      3  | 
|         |      4  | 
|         |      5 object M4a { | 
|         |      6  | 
|         |      7 // If you need any auxiliary functions, feel free to  | 
|         |      8 // implement them, but do not make any changes to the | 
|         |      9 // templates below. Also have a look whether the functions | 
|         |     10 // at the end of the file are of any help. | 
|         |     11  | 
|         |     12  | 
|         |     13  | 
|         |     14 type Pos = (Int, Int)    // a position on a chessboard  | 
|         |     15 type Path = List[Pos]    // a path...a list of positions | 
|         |     16  | 
|         |     17 //(1) Complete the function that tests whether the position x | 
|         |     18 //    is inside the board and not yet element in the path. | 
|         |     19  | 
|         |     20 def is_legal(dim: Int, path: Path, x: Pos) : Boolean = ??? | 
|         |     21  | 
|         |     22  | 
|         |     23  | 
|         |     24 //(2) Complete the function that calculates for a position x | 
|         |     25 //    all legal onward moves that are not already in the path.  | 
|         |     26 //    The moves should be ordered in a "clockwise" manner. | 
|         |     27   | 
|         |     28 def legal_moves(dim: Int, path: Path, x: Pos) : List[Pos] = ??? | 
|         |     29  | 
|         |     30  | 
|         |     31 //some testcases | 
|         |     32 // | 
|         |     33 //assert(legal_moves(8, Nil, (2,2)) ==  | 
|         |     34 //  List((3,4), (4,3), (4,1), (3,0), (1,0), (0,1), (0,3), (1,4))) | 
|         |     35 //assert(legal_moves(8, Nil, (7,7)) == List((6,5), (5,6))) | 
|         |     36 //assert(legal_moves(8, List((4,1), (1,0)), (2,2)) ==  | 
|         |     37 //  List((3,4), (4,3), (3,0), (0,1), (0,3), (1,4))) | 
|         |     38 //assert(legal_moves(8, List((6,6)), (7,7)) == List((6,5), (5,6))) | 
|         |     39  | 
|         |     40  | 
|         |     41 //(3) Complete the two recursive functions below.  | 
|         |     42 //    They exhaustively search for knight's tours starting from the  | 
|         |     43 //    given path. The first function counts all possible tours,  | 
|         |     44 //    and the second collects all tours in a list of paths. | 
|         |     45  | 
|         |     46 def count_tours(dim: Int, path: Path) : Int = ??? | 
|         |     47  | 
|         |     48 def enum_tours(dim: Int, path: Path) : List[Path] = ??? | 
|         |     49  | 
|         |     50  | 
|         |     51 //(4) Implement a first-function that finds the first  | 
|         |     52 //    element, say x, in the list xs where f is not None.  | 
|         |     53 //    In that case Return f(x), otherwise None. If possible, | 
|         |     54 //    calculate f(x) only once. | 
|         |     55  | 
|         |     56 def first(xs: List[Pos], f: Pos => Option[Path]) : Option[Path] = ??? | 
|         |     57  | 
|         |     58  | 
|         |     59 // testcases | 
|         |     60 // | 
|         |     61 //def foo(x: (Int, Int)) = if (x._1 > 3) Some(List(x)) else None | 
|         |     62 // | 
|         |     63 //first(List((1, 0),(2, 0),(3, 0),(4, 0)), foo)   // Some(List((4,0))) | 
|         |     64 //first(List((1, 0),(2, 0),(3, 0)), foo)          // None | 
|         |     65  | 
|         |     66  | 
|         |     67 //(5) Implement a function that uses the first-function from (4) for | 
|         |     68 //    trying out onward moves, and searches recursively for a | 
|         |     69 //    knight tour on a dim * dim-board. | 
|         |     70  | 
|         |     71 def first_tour(dim: Int, path: Path) : Option[Path] = ??? | 
|         |     72   | 
|         |     73  | 
|         |     74  | 
|         |     75 /* Helper functions | 
|         |     76  | 
|         |     77  | 
|         |     78 // for measuring time | 
|         |     79 def time_needed[T](code: => T) : T = { | 
|         |     80   val start = System.nanoTime() | 
|         |     81   val result = code | 
|         |     82   val end = System.nanoTime() | 
|         |     83   println(f"Time needed: ${(end - start) / 1.0e9}%3.3f secs.") | 
|         |     84   result | 
|         |     85 } | 
|         |     86  | 
|         |     87 // can be called for example with | 
|         |     88 // | 
|         |     89 //     time_needed(count_tours(dim, List((0, 0)))) | 
|         |     90 // | 
|         |     91 // in order to print out the time that is needed for  | 
|         |     92 // running count_tours | 
|         |     93  | 
|         |     94  | 
|         |     95 // for printing a board | 
|         |     96 def print_board(dim: Int, path: Path): Unit = { | 
|         |     97   println() | 
|         |     98   for (i <- 0 until dim) { | 
|         |     99     for (j <- 0 until dim) { | 
|         |    100       print(f"${path.reverse.indexOf((j, dim - i - 1))}%3.0f ") | 
|         |    101     } | 
|         |    102     println() | 
|         |    103   }  | 
|         |    104 } | 
|         |    105  | 
|         |    106  | 
|         |    107 */ | 
|         |    108  | 
|         |    109 } |