diff -r 0587ef444547 -r 48de09728447 Attic/sudoku_test.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Attic/sudoku_test.scala Sat Mar 11 23:24:15 2023 +0000 @@ -0,0 +1,88 @@ +// Sudoku +//======== + +// call parallel version with +// +// scala -cp scala-parallel-collections_2.13-0.2.0.jar sudoku_test.scala +// +// or +// +// scalac -cp scala-parallel-collections_2.13-0.2.0.jar sudoku_test.scala +// java -cp .:scala-library-2.13.0.jar:scala-parallel-collections_2.13-0.2.0.jar Sudoku + +object Sudoku extends App { + +import scala.collection.parallel.CollectionConverters._ + +type Pos = (Int, Int) +val emptyValue = '.' +val maxValue = 9 + +val allValues = "123456789".toList +val indexes = (0 to 8).toList + + +def empty(game: String) = game.indexOf(emptyValue) +def isDone(game: String) = empty(game) == -1 +def emptyPosition(game: String) = { + val e = empty(game) + (e % maxValue, e / maxValue) +} + + +def get_row(game: String, y: Int) = indexes.map(col => game(y * maxValue + col)) +def get_col(game: String, x: Int) = indexes.map(row => game(x + row * maxValue)) + +def get_box(game: String, pos: Pos): List[Char] = { + def base(p: Int): Int = (p / 3) * 3 + val x0 = base(pos._1) + val y0 = base(pos._2) + for (x <- (x0 until x0 + 3).toList; + y <- (y0 until y0 + 3).toList) yield game(x + y * maxValue) +} + + +def update(game: String, pos: Int, value: Char): String = + game.updated(pos, value) + +def toAvoid(game: String, pos: Pos): List[Char] = + (get_col(game, pos._1) ++ get_row(game, pos._2) ++ get_box(game, pos)) + +def candidates(game: String, pos: Pos): List[Char] = + allValues.diff(toAvoid(game, pos)) + +def search(game: String): List[String] = { + if (isDone(game)) List(game) + else { + val cs = candidates(game, emptyPosition(game)) + cs.par.map(c => search(update(game, empty(game), c))).toList.flatten + } +} + + +def pretty(game: String): String = + "\n" + (game.grouped(maxValue).mkString(",\n")) + + +val game2 = """8........ + |..36..... + |.7..9.2.. + |.5...7... + |....457.. + |...1...3. + |..1....68 + |..85...1. + |.9....4..""".stripMargin.replaceAll("\\n", "") + +// for measuring time +def time_needed[T](i: Int, code: => T) = { + val start = System.nanoTime() + for (j <- 1 to i) code + val end = System.nanoTime() + s"${(end - start) / 1.0e9} secs" +} + + +println(time_needed(10, search(game2))) + +}