Last active
February 15, 2020 09:57
-
-
Save ayeo/8314c6472dc9290b9fc3cf11ad70c6b8 to your computer and use it in GitHub Desktop.
Scala Sudoku Solver
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.collection.immutable.{Vector => $} | |
/** | |
* This is highly inspired by https://gist.github.com/pathikrit/a32e17832296befd6b94 | |
* Actually only main recurssion block is changed for better readability | |
* | |
* See also excellent Computerphile video https://www.youtube.com/watch?v=G_UYXzGuqvM | |
*/ | |
object Solver { | |
val n = 9 | |
val s = Math.sqrt(n).toInt | |
type Board = Vector[Vector[Int]] | |
private def possibleDigits(board: Board, r: Int, c: Int): Seq[Int] = { | |
def cells(i: Int) = Seq(board(r)(i), board(i)(c), board(s * (r / s) + i / s)(s * (c / s) + i % s)) | |
val used = board.indices.flatMap(cells) | |
(1 to 9).diff(used) | |
} | |
def solve(board: Board, cell: Int = 0): Option[Board] = (cell % n, cell / n) match { | |
case (0, 9) => Some(board) //cell=81 board is solved | |
case (r, c) if board(r)(c) > 0 => solve(board, cell + 1) //cell is already filled, go to next | |
case (r, c) => | |
possibleDigits(board, r, c) | |
.flatMap(n => solve(board.updated(r, board(r).updated(c, n)))) //find next solution for each digit | |
.headOption //return first non-empty element (the ultimate solution) otherwise None | |
} | |
def print(board: Board): Unit = println(board.map(_.mkString(" ")).mkString("\n")) | |
} | |
object SudokuSolver extends App { | |
val board = $( | |
$(8, 0, 0, 0, 0, 7, 0, 9, 0), | |
$(0, 7, 0, 0, 2, 0, 0, 0, 8), | |
$(0, 0, 9, 6, 0, 0, 5, 0, 0), | |
$(0, 0, 5, 3, 0, 0, 9, 0, 0), | |
$(0, 1, 0, 0, 8, 0, 0, 0, 2), | |
$(6, 0, 0, 0, 0, 4, 0, 0, 0), | |
$(3, 0, 0, 0, 0, 0, 0, 1, 0), | |
$(0, 4, 0, 0, 0, 0, 0, 0, 7), | |
$(0, 0, 7, 0, 0, 0, 3, 0, 0) | |
) | |
Solver.solve(board).map(Solver.print) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment