| author | Christian Urban <christian.urban@kcl.ac.uk> | 
| Thu, 02 Nov 2023 23:34:53 +0000 | |
| changeset 472 | fbff6f601370 | 
| parent 421 | 864107857d27 | 
| permissions | -rw-r--r-- | 
| 391 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 1 | // Part 3 about finding a single tour using the Warnsdorf Rule | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 2 | //============================================================= | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 3 | |
| 421 | 4 | object M4c { // for preparing the jar
 | 
| 391 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 5 | |
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 6 | type Pos = (Int, Int) | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 7 | type Path = List[Pos] | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 8 | |
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 9 | |
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 10 | // for measuring time in the JAR | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 11 | def time_needed[T](code: => T) : T = {
 | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 12 | val start = System.nanoTime() | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 13 | val result = code | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 14 | val end = System.nanoTime() | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 15 |   println(f"Time needed: ${(end - start) / 1.0e9}%3.3f secs.")
 | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 16 | result | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 17 | } | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 18 | |
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 19 | |
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 20 | def print_board(dim: Int, path: Path): Unit = {
 | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 21 | println() | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 22 |   for (i <- 0 until dim) {
 | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 23 |     for (j <- 0 until dim) {
 | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 24 |       print(f"${path.reverse.indexOf((i, j))}%4.0f ")
 | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 25 | } | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 26 | println() | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 27 | } | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 28 | } | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 29 | |
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 30 | def add_pair(x: Pos, y: Pos): Pos = | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 31 | (x._1 + y._1, x._2 + y._2) | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 32 | |
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 33 | def is_legal(dim: Int, path: Path, x: Pos): Boolean = | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 34 | 0 <= x._1 && 0 <= x._2 && x._1 < dim && x._2 < dim && !path.contains(x) | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 35 | |
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 36 | def moves(x: Pos): List[Pos] = | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 37 | List(( 1, 2),( 2, 1),( 2, -1),( 1, -2), | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 38 | (-1, -2),(-2, -1),(-2, 1),(-1, 2)).map(add_pair(x, _)) | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 39 | |
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 40 | def legal_moves(dim: Int, path: Path, x: Pos): List[Pos] = | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 41 | moves(x).filter(is_legal(dim, path, _)) | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 42 | |
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 43 | def ordered_moves(dim: Int, path: Path, x: Pos): List[Pos] = | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 44 | legal_moves(dim, path, x).sortBy((x) => legal_moves(dim, path, x).length) | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 45 | |
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 46 | import scala.annotation.tailrec | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 47 | |
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 48 | @tailrec | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 49 | def tour_on_mega_board_aux(dim: Int, paths: List[Path]): Option[Path] = paths match {
 | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 50 | case Nil => None | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 51 | case (path::rest) => | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 52 | if (path.length == dim * dim) Some(path) | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 53 | else tour_on_mega_board_aux(dim, ordered_moves(dim, path, path.head).map(_::path) ::: rest) | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 54 | } | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 55 | |
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 56 | def ttour_on_mega_board(dim: Int, path: Path): Option[Path] = | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 57 | tour_on_mega_board_aux(dim, List(path)) | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 58 | |
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 59 | |
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 60 | def tour_on_mega_board(dim: Int, path: Path) = | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 61 | time_needed(ttour_on_mega_board(dim: Int, path: Path)) | 
| 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 62 | |
| 421 | 63 | |
| 64 | // testcases | |
| 65 | //print_board(70, tour_on_mega_board(70, List((0, 0))).get) | |
| 66 | ||
| 391 
048fc6b70776
added main4 marking
 Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset | 67 | } |