progs/knight2.scala
changeset 50 9891c9fac37e
parent 44 9cfa37c91444
child 213 f968188d4a9b
equal deleted inserted replaced
49:fdc2c6fb7a24 50:9891c9fac37e
       
     1 // Part 2 about finding a single tour for a board
       
     2 //================================================
     1 
     3 
     2 type Pos = (Int, Int)
     4 // copy any function you need from file knight1.scala
     3 type Path = List[Pos]
       
     4 
     5 
     5 def print_board(dim: Int, path: Path): Unit = {
     6 type Pos = (Int, Int)    // a position on a chessboard 
     6   println
     7 type Path = List[Pos]    // a path...a list of positions
     7   for (i <- 0 until dim) {
       
     8     for (j <- 0 until dim) {
       
     9       print(f"${path.indexOf((i, j))}%3.0f ")
       
    10     }
       
    11     println
       
    12   } 
       
    13 }
       
    14 
     8 
    15 
     9 
    16 def add_pair(x: Pos)(y: Pos): Pos = 
    10 //(2a) Implement a first-function that finds the first 
    17   (x._1 + y._1, x._2 + y._2)
    11 // element, say x, in the list xs where f is not None. 
       
    12 // In that case return f(x), otherwise none.
    18 
    13 
    19 def is_legal(dim: Int, path: Path)(x: Pos): Boolean = 
    14 def first(xs: List[Pos], f: Pos => Option[Path]): Option[Path] = ...
    20   0 <= x._1 && 0 <= x._2 && x._1 < dim && x._2 < dim && !path.contains(x)
       
    21 
    15 
    22 def moves(x: Pos): List[Pos] = {
    16 //(2b) Implement a function that uses the first-function for
    23   List(( 1,  2),( 2,  1),( 2, -1),( 1, -2),
    17 // trying out onward moves, and searches recursively for an 
    24        (-1, -2),(-2, -1),(-2,  1),(-1,  2)).map(add_pair(x))
    18 // *open* tour on a dim * dim-board.
    25 }
       
    26 
    19 
    27 def legal_moves(dim: Int, path: Path, x: Pos): List[Pos] = 
    20 def first_tour(dim: Int, path: Path): Option[Path] = ...
    28   moves(x).filter(is_legal(dim, path))
    21  
    29 
       
    30 
       
    31 
       
    32 // non-circle tours
       
    33 /*
       
    34 def tour(dim: Int, path: List[Pos]): List[List[Pos]] = {
       
    35   if (path.length ==  dim * dim) // && moves(n)(path.head).contains(path.last)) 
       
    36     List(path)
       
    37   else 
       
    38     (for (x <- legal_moves(dim, path, path.head)) yield tour(dim, x::path)).flatten
       
    39 }
       
    40 */
       
    41 
       
    42 def tour(dim: Int, path: Path): Int = {
       
    43   if (path.length == dim * dim) 1
       
    44   else 
       
    45     (for (x <- legal_moves(dim, path, path.head) yield tour(dim, x::path))).sum
       
    46 }
       
    47 
       
    48 
       
    49 def dtour(dim: Int): List[List[Pos]] = {
       
    50   var counter = 100000000
       
    51 
       
    52   def etour(dim: Int, path: List[Pos]): List[List[Pos]] = {
       
    53     counter = counter - 1
       
    54     if (counter <= 0) List() else
       
    55       if (path.length == dim * dim) List(path)
       
    56       else 
       
    57         (for (x <- legal_moves(dim, path, path.head)) yield etour(dim, x::path)).flatten
       
    58   }
       
    59 
       
    60   (for (i <- (0 until dim).toList; 
       
    61         j <- (0 until dim).toList) yield etour(dim, List((i, j)))).flatten
       
    62 }
       
    63 
       
    64 
       
    65 
       
    66 //val n = 8
       
    67 val n = 5
       
    68 println(s"number simple tours: n = $n")
       
    69 
       
    70 //println(etour(n, List((0, 0))).size)
       
    71 
       
    72 
       
    73 
       
    74 for (d <- 9 to 9) {
       
    75   println(s"${d} x ${d} " + dtour(d).length)
       
    76 }
       
    77 
       
    78