progs/cube.scala
changeset 463 0315d9983cd0
parent 417 29fc780ca130
child 464 73ced118f73d
equal deleted inserted replaced
462:34feeb53c0ba 463:0315d9983cd0
     1 // 2 x 2 x 2 Rubik's Cube
     1 // 2 x 2 x 2 Rubik's Cube
     2 //========================
     2 //========================
     3 
     3 
     4 // more memory for the JVM
     4 // for more memory for the JVM, call
     5 //
     5 //
     6 // JAVA_OPTS="-Xmx2g" scala
     6 // JAVA_OPTS="-Xmx2g" scala
     7 
     7 
     8 
     8 
     9 // for measuring memory usage
     9 // for measuring memory usage
    92          Face(c.f4.c11, c.f4.c12, c.f6.c12, c.f6.c11),
    92          Face(c.f4.c11, c.f4.c12, c.f6.c12, c.f6.c11),
    93          Face(c.f4.c22, c.f4.c21, c.f5.c21, c.f5.c22),
    93          Face(c.f4.c22, c.f4.c21, c.f5.c21, c.f5.c22),
    94          Face(c.f1.c11, c.f1.c12, c.f6.c21, c.f6.c22))         
    94          Face(c.f1.c11, c.f1.c12, c.f6.c21, c.f6.c22))         
    95 
    95 
    96 
    96 
    97 // simple bf-search without solution, just true
    97 // simple bf-search without generating a solution, just true
    98 
    98 
    99 def actions(c: Cube) : List[Cube] = 
    99 def actions(c: Cube) : List[Cube] = 
   100   List(up(c), clock(c), right(c)) 
   100   List(up(c), clock(c), right(c)) 
   101 
   101 
   102 def search(cs: List[Cube], d: Int) : Boolean = { 
   102 def search(cs: List[Cube], d: Int) : Boolean = { 
   106   else search(cs.flatMap(actions), d + 1)
   106   else search(cs.flatMap(actions), d + 1)
   107 }  
   107 }  
   108 
   108 
   109 search(List(init), 0)
   109 search(List(init), 0)
   110 
   110 
   111 // Set version
   111 
       
   112 // set version
   112 def actions_set(c: Cube) : Set[Cube] =
   113 def actions_set(c: Cube) : Set[Cube] =
   113   Set(up(c), clock(c), right(c))
   114   Set(up(c), clock(c), right(c))
   114 
   115 
   115 def search_set(cs: Set[Cube], d: Int) : Boolean = {
   116 def search_set(cs: Set[Cube], d: Int) : Boolean = {
   116   println(s"Depth: $d candidates: ${cs.size}")
   117   println(s"Depth: $d candidates: ${cs.size}")
   120 }  
   121 }  
   121 
   122 
   122 search_set(Set(init), 0)
   123 search_set(Set(init), 0)
   123 
   124 
   124 
   125 
   125 // For generating list of actions
   126 // for generating list of actions
   126 abstract class Action
   127 abstract class Action
   127 case object Up extends Action
   128 case object Up extends Action
   128 case object Right extends Action
   129 case object Right extends Action
   129 case object Clock extends Action
   130 case object Clock extends Action
   130 
   131 
   131 type Actions = List[Action]
   132 type Actions = List[Action]
   132 
   133 
   133 // List version generating a list of actions
   134 // list version generating a list of actions
   134 def actions_list(c: Cube, act: Actions) : List[(Cube, Actions)] = 
   135 def actions_list(c: Cube, act: Actions) : List[(Cube, Actions)] = 
   135   List((up(c), Up::act), 
   136   List((up(c), Up::act), 
   136        (clock(c), Clock::act), 
   137        (clock(c), Clock::act), 
   137        (right(c), Right::act)) 
   138        (right(c), Right::act)) 
   138 
   139 
   145 }  
   146 }  
   146 
   147 
   147 search_list(List((init, Nil)), 0)._2.reverse.mkString("\n") 
   148 search_list(List((init, Nil)), 0)._2.reverse.mkString("\n") 
   148 
   149 
   149 
   150 
   150 // Map version generating a list of actions
   151 // map version generating a list of actions
   151 def actions_map(c: Cube, as: Actions) : Map[Cube, Actions] = 
   152 def actions_map(c: Cube, as: Actions) : Map[Cube, Actions] = 
   152   Map(up(c) -> (Up::as), 
   153   Map(up(c) -> (Up::as), 
   153       clock(c) -> (Clock::as), 
   154       clock(c) -> (Clock::as), 
   154       right(c) -> (Right::as)) 
   155       right(c) -> (Right::as)) 
   155 
   156 
   164 
   165 
   165 search_map(Map(init -> Nil), 0).reverse.mkString("\n")
   166 search_map(Map(init -> Nil), 0).reverse.mkString("\n")
   166 
   167 
   167 
   168 
   168 
   169 
   169 // Bidirectional breadth-first search
   170 // bidirectional breadth-first search
   170 def bsearch(cs: Map[Cube, Actions], 
   171 def bsearch(cs: Map[Cube, Actions], 
   171             bs: Map[Cube, Actions], d: Int) : Actions = { 
   172             bs: Map[Cube, Actions], d: Int) : Actions = { 
   172   println(s"Depth: $d    Cands: ${cs.keySet.size}/${bs.keySet.size}") 
   173   println(s"Depth: $d    Cands: ${cs.keySet.size}/${bs.keySet.size}") 
   173   val res = cs.keySet intersect bs.keySet 
   174   val res = cs.keySet intersect bs.keySet 
   174   if (!res.isEmpty) (cs(res.head).reverse ::: bs(res.head))
   175   if (!res.isEmpty) (cs(res.head).reverse ::: bs(res.head))
   178 
   179 
   179 bsearch(Map(init ->  Nil), Map(solved -> Nil), 0).mkString("\n")
   180 bsearch(Map(init ->  Nil), Map(solved -> Nil), 0).mkString("\n")
   180 
   181 
   181 
   182 
   182 
   183 
   183 
   184 // bidirectional breadth-first search
   184 
   185 def bsearch(cs: Map[Cube, Actions], 
   185 
   186             bs: Map[Cube, Actions], d: Int) : Actions = { 
   186 
   187   println(s"Depth: $d    Cands: ${cs.keySet.size}/${bs.keySet.size}") 
   187 
   188   val res = cs.keySet intersect bs.keySet 
   188 
   189   if (!res.isEmpty) (cs(res.head).reverse ::: bs(res.head))
   189 
   190   else bsearch(cs.flatMap{ (c, as) => actions_map(c, as) }, 
   190 
   191                bs.flatMap{ (c, as) => actions_map(c, as) }, d + 1)
   191 
   192 }  
   192 
   193 
   193 
   194 bsearch(Map(init ->  Nil), Map(solved -> Nil), 0).mkString("\n")
   194 
   195 
   195 
   196 
   196 
   197 
   197 
   198 
   198 
   199 
   199 
   200 
       
   201 
       
   202 
       
   203 
       
   204 
       
   205 
       
   206 
       
   207 
       
   208 
       
   209 
       
   210 
       
   211 
       
   212 
       
   213 
       
   214