progs/lecture4.scala
changeset 383 c02929f2647c
parent 382 1bd800376e0c
child 384 6e1237691307
equal deleted inserted replaced
382:1bd800376e0c 383:c02929f2647c
   269               |5....9.6.
   269               |5....9.6.
   270               |..6.2..3.
   270               |..6.2..3.
   271               |1..5...92
   271               |1..5...92
   272               |..7.9.41.""".stripMargin.replaceAll("\\n", "")
   272               |..7.9.41.""".stripMargin.replaceAll("\\n", "")
   273 
   273 
   274 candidates(game0, (0, 0))
   274 
   275 
   275 
   276 type Pos = (Int, Int)
   276 type Pos = (Int, Int)
   277 val EmptyValue = '.'
   277 val EmptyValue = '.'
   278 val MaxValue = 9
   278 val MaxValue = 9
   279 
   279 
       
   280 def pretty(game: String): String = 
       
   281   "\n" + (game.grouped(MaxValue).mkString("\n"))
       
   282 
       
   283 pretty(game0)
       
   284 
       
   285 
   280 val allValues = "123456789".toList
   286 val allValues = "123456789".toList
   281 val indexes = (0 to 8).toList
   287 val indexes = (0 to 8).toList
   282 
   288 
   283 
       
   284 def empty(game: String) = game.indexOf(EmptyValue)
   289 def empty(game: String) = game.indexOf(EmptyValue)
   285 def isDone(game: String) = empty(game) == -1 
   290 def isDone(game: String) = empty(game) == -1 
   286 def emptyPosition(game: String) = 
   291 def emptyPosition(game: String) = {
   287   (empty(game) % MaxValue, empty(game) / MaxValue)
   292   val e = empty(game)
   288 
   293   (e % MaxValue, e / MaxValue)
       
   294 }
   289 
   295 
   290 def get_row(game: String, y: Int) = 
   296 def get_row(game: String, y: Int) = 
   291   indexes.map(col => game(y * MaxValue + col))
   297   indexes.map(col => game(y * MaxValue + col))
   292 def get_col(game: String, x: Int) = 
   298 def get_col(game: String, x: Int) = 
   293   indexes.map(row => game(x + row * MaxValue))
   299   indexes.map(row => game(x + row * MaxValue))
   294 
   300 
   295 get_row(game0, 0)
   301 //get_row(game0, 0)
       
   302 //get_row(game0, 1)
       
   303 //get_col(game0, 0)
   296 
   304 
   297 def get_box(game: String, pos: Pos): List[Char] = {
   305 def get_box(game: String, pos: Pos): List[Char] = {
   298     def base(p: Int): Int = (p / 3) * 3
   306     def base(p: Int): Int = (p / 3) * 3
   299     val x0 = base(pos._1)
   307     val x0 = base(pos._1)
   300     val y0 = base(pos._2)
   308     val y0 = base(pos._2)
   301     val ys = (y0 until y0 + 3).toList
   309     val ys = (y0 until y0 + 3).toList
   302     (x0 until x0 + 3).toList.flatMap(x => ys.map(y => game(x + y * MaxValue)))
   310     (x0 until x0 + 3).toList
   303 }
   311       .flatMap(x => ys.map(y => game(x + y * MaxValue)))
   304 
   312 }
   305 //get_row(game0, 0)
   313 
   306 //get_row(game0, 1)
   314 
   307 //get_col(game0, 0)
       
   308 //get_box(game0, (3, 1))
   315 //get_box(game0, (3, 1))
   309 
   316 
   310 
   317 
   311 // this is not mutable!!
   318 // this is not mutable!!
   312 def update(game: String, pos: Int, value: Char): String = 
   319 def update(game: String, pos: Int, value: Char): String = 
   313   game.updated(pos, value)
   320   game.updated(pos, value)
   314 
   321 
   315 def toAvoid(game: String, pos: Pos): List[Char] = 
   322 def toAvoid(game: String, pos: Pos): List[Char] = 
   316   (get_col(game, pos._1) ++ get_row(game, pos._2) ++ get_box(game, pos))
   323   (get_col(game, pos._1) ++ 
       
   324    get_row(game, pos._2) ++ 
       
   325    get_box(game, pos))
   317 
   326 
   318 def candidates(game: String, pos: Pos): List[Char] = 
   327 def candidates(game: String, pos: Pos): List[Char] = 
   319   allValues.diff(toAvoid(game, pos))
   328   allValues.diff(toAvoid(game, pos))
   320 
   329 
   321 //candidates(game0, (0,0))
   330 //candidates(game0, (0,0))
   322 
   331 
   323 def pretty(game: String): String = 
       
   324   "\n" + (game.sliding(MaxValue, MaxValue).mkString("\n"))
       
   325 
   332 
   326 def search(game: String): List[String] = {
   333 def search(game: String): List[String] = {
   327   if (isDone(game)) List(game)
   334   if (isDone(game)) List(game)
   328   else {
   335   else {
   329     val cs = candidates(game, emptyPosition(game))
   336     val cs = candidates(game, emptyPosition(game))
   330     cs.map(c => search(update(game, empty(game), c))).toList.flatten
   337     cs.map(c => search(update(game, empty(game), c))).flatten
   331   }
   338   }
   332 }
   339 }
   333 
   340 
   334 List(List("sol1"), List("sol2", "sol3")).flatten
   341 pretty(game0)
   335 
       
   336 search(game0).map(pretty)
   342 search(game0).map(pretty)
   337 
   343 
   338 val game1 = """23.915...
   344 val game1 = """23.915...
   339               |...2..54.
   345               |...2..54.
   340               |6.7......
   346               |6.7......