Skip to content

Instantly share code, notes, and snippets.

@daimatz
Created September 30, 2013 09:28
Show Gist options
  • Save daimatz/6761365 to your computer and use it in GitHub Desktop.
Save daimatz/6761365 to your computer and use it in GitHub Desktop.
適当に書いた数独 (Scala)
object Sudoku {
val N = 9
val ROOM = Math.sqrt(N).asInstanceOf[Int]
type Coord = (Int, Int)
def nextCoord(coord: Coord): Coord = {
if (coord._2 == N - 1) {
return if (coord._1 == N-1) (0, 0) else (coord._1 + 1, 0)
} else {
return (coord._1, coord._2 + 1)
}
}
class Field(ary: Array[Array[Int]]) {
val field = ary
def get(c: Coord): Int = {
return field(c._1)(c._2)
}
def put(c: Coord, k: Int) {
if (k == 0 || can_put(c, k))
field(c._1)(c._2) = k
}
def can_put(c: Coord, k: Int): Boolean = {
//println(k)
def room: Boolean = {
for (i <- 0 to ROOM - 1)
if (field(i + ROOM * (c._1 / ROOM))
.drop(ROOM * (c._2 / ROOM)).take(ROOM).contains(k))
return true
return false
}
return !(field(c._1).contains(k)
|| field.map(_(c._2)).contains(k)
|| room)
}
def all_filled(): Boolean = {
return !(field.map(_.contains(0)).contains(true))
}
def dump(): Unit = {
field.map(_.mkString).map(println)
}
}
class Problem(problem: Field) {
val original = problem
def solve(): Unit = {
val current = original
inner_solve((0,0), current)
}
private def inner_solve(c: Coord, current: Field): Unit = {
//println(c)
if (current.all_filled) {
current.dump()
//println("Found!")
return
}
if (current.get(c) != 0) {
inner_solve(nextCoord(c), current)
} else {
for (k <- 1 to N) {
if (current.can_put(c, k)) {
//println("put: " + c + ", " + k)
current.put(c, k)
inner_solve(nextCoord(c), current)
current.put(c, 0)
}
}
}
}
}
def main(args: Array[String]): Unit = {
val input = new Array[Array[Int]](9)
for (i <- 0 to 8) {
val line = readLine()
input(i) = new Array[Int](9)
for (j <- 0 to 8)
input(i)(j) = line(j) - '0'
}
val problem = new Problem(new Field(input))
problem.solve()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment