progs/knight3_sol.scala
changeset 66 3506b681c191
parent 53 9f8751912560
--- a/progs/knight3_sol.scala	Tue Nov 22 01:35:40 2016 +0000
+++ b/progs/knight3_sol.scala	Wed Nov 23 13:32:01 2016 +0000
@@ -31,7 +31,10 @@
 def ordered_moves(dim: Int, path: Path, x: Pos): List[Pos] = 
   legal_moves(dim, path, x).sortBy((x) => legal_moves(dim, path, x).length)
 
+import scala.annotation.tailrec
 
+/*
+@tailrec
 def first(xs: List[Pos], f: Pos => Option[Path]): Option[Path] = xs match {
   case Nil => None
   case x::xs => {
@@ -39,6 +42,10 @@
     if (result.isDefined) result else first(xs, f)
   }
 }
+*/
+
+def first[A, B](xs: List[A], f: A => Option[B]): Option[B] =
+  xs.flatMap(f(_)).headOption
 
 
 def first_closed_tour_heuristics(dim: Int, path: Path): Option[Path] = {
@@ -47,19 +54,46 @@
     first(ordered_moves(dim, path, path.head), (x: Pos) => first_closed_tour_heuristics(dim, x::path))
 }
 
+/*
 for (dim <- 1 to 6) {
   val t = first_closed_tour_heuristics(dim, List((dim / 2, dim / 2)))
   println(s"${dim} x ${dim} closed: " + (if (t == None) "" else { print_board(dim, t.get) ; "" }))
 }
+*/
+
+//@tailrec
+def first_tour_heuristics(dim: Int, path: Path): Option[Path] = {
+
+  @tailrec
+  def aux(dim: Int, path: Path, moves: List[Position]): Option[Path 
+  if (path.length == dim * dim) Some(path)
+  else
+    moves match {
+      case Nil => None
+      case x::xs => {
+        val r = first_tour_heuristics(dim, x::path)
+        if (r.isDefined) Some(r) else aux(dim, path, xs)
+    }    
+  aux(dim, path, ordered_moves(dim, path, path.head)) 
+}
 
 
+/*
 def first_tour_heuristics(dim: Int, path: Path): Option[Path] = {
   if (path.length == dim * dim) Some(path)
   else
-    first(ordered_moves(dim, path, path.head), (x: Pos) => first_tour_heuristics(dim, x::path))
+    for (p <- ordered_moves(dim, path, path.head))
+      val r = first_tour_heuristics(dim, x::path)
+    //first(ordered_moves(dim, path, path.head), (x: Pos) => first_tour_heuristics(dim, x::path))
+    ordered_moves(dim, path, path.head).view.flatMap((x: Pos) => first_tour_heuristics(dim, x::path)).headOption
 }
+*/ 
 
+/*
 for (dim <- 1 to 50) {
   val t = first_tour_heuristics(dim, List((dim / 2, dim / 2)))
   println(s"${dim} x ${dim}: " + (if (t == None) "" else { print_board(dim, t.get) ; "" }))
 }
+*/
+
+print_board(50, first_tour_heuristics(50, (25,25)::Nil).get)