Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
132
Task/Sudoku/Scala/sudoku-1.scala
Normal file
132
Task/Sudoku/Scala/sudoku-1.scala
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
object SudokuSolver extends App {
|
||||
|
||||
class Solver {
|
||||
|
||||
var solution = new Array[Int](81) //listOfFields toArray
|
||||
|
||||
val fp2m: Int => Tuple2[Int,Int] = pos => Pair(pos/9+1,pos%9+1) //get row, col from array position
|
||||
val setAll = (1 to 9) toSet //all possibilities
|
||||
|
||||
val arrayGroups = new Array[List[List[Int]]](81)
|
||||
val sv: Int => Int = (row: Int) => (row-1)*9 //start value group row
|
||||
val ev: Int => Int = (row: Int) => sv(row)+8 //end value group row
|
||||
val fgc: (Int,Int) => Int = (i,col) => i*9+col-1 //get group col
|
||||
val fgs: Int => (Int,Int) = p => Pair(p, p/(27)*3+p%9/3) //get group square box
|
||||
for (pos <- 0 to 80) {
|
||||
val (row,col) = fp2m(pos)
|
||||
val gRow = (sv(row) to ev(row)).toList
|
||||
val gCol = ((0 to 8) toList) map (fgc(_,col))
|
||||
val gSquare = (0 to 80 toList) map fgs filter (_._2==(fgs(pos))._2) map (_._1)
|
||||
arrayGroups(pos) = List(gRow,gCol,gSquare)
|
||||
}
|
||||
val listGroups = arrayGroups toList
|
||||
|
||||
val fpv4s: (Int) => List[Int] = pos => { //get possible values for solving
|
||||
val setRow = (listGroups(pos)(0) map (solution(_))).toSet
|
||||
val setCol = listGroups(pos)(1).map(solution(_)).toSet
|
||||
val setSquare = listGroups(pos)(2).map(solution(_)).toSet
|
||||
val setG = setRow++setCol++setSquare--Set(0)
|
||||
val setPossible = setAll--setG
|
||||
setPossible.toList.sortWith(_<_)
|
||||
}
|
||||
|
||||
|
||||
//solve the riddle: Nil ==> solution does not exist
|
||||
def solve(listOfFields: List[Int]): List[Int] = {
|
||||
solution = listOfFields toArray
|
||||
|
||||
def checkSol(uncheckedSol: List[Int]): List[Int] = {
|
||||
if (uncheckedSol == Nil) return Nil
|
||||
solution = uncheckedSol toArray
|
||||
val check = (0 to 80).map(fpv4s(_)).filter(_.size>0)
|
||||
if (check == Nil) return uncheckedSol
|
||||
return Nil
|
||||
}
|
||||
|
||||
val f1: Int => Pair[Int,Int] = p => Pair(p,listOfFields(p))
|
||||
val numFields = (0 to 80 toList) map f1 filter (_._2==0)
|
||||
val iter = numFields map ((_: (Int,Int))._1)
|
||||
var p_iter = 0
|
||||
|
||||
val first: () => Int = () => {
|
||||
val ret = numFields match {
|
||||
case Nil => -1
|
||||
case _ => numFields(0)._1
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
val last: () => Int = () => {
|
||||
val ret = numFields match {
|
||||
case Nil => -1
|
||||
case _ => numFields(numFields.size-1)._1
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
val hasPrev: () => Boolean = () => p_iter > 0
|
||||
val prev: () => Int = () => {p_iter -= 1; iter(p_iter)}
|
||||
val hasNext: () => Boolean = () => p_iter < iter.size-1
|
||||
val next: () => Int = () => {p_iter += 1; iter(p_iter)}
|
||||
val fixed: Int => Boolean = pos => listOfFields(pos) != 0
|
||||
val possiArray = new Array[List[Int]](numFields.size)
|
||||
val firstUF = first() //first unfixed
|
||||
if (firstUF < 0) return checkSol(solution.toList) //that is it!
|
||||
var pif = iter(p_iter) //pos in fields
|
||||
val lastUF = last() //last unfixed
|
||||
val (row,col) = fp2m(pif)
|
||||
possiArray(p_iter) = fpv4s(pif).toList.sortWith(_<_)
|
||||
|
||||
while(pif <= lastUF) {
|
||||
val (row,col) = fp2m(pif)
|
||||
if (possiArray(p_iter) == null) possiArray(p_iter) = fpv4s(pif).toList.sortWith(_<_)
|
||||
val possis = possiArray(p_iter)
|
||||
if (possis.isEmpty) {
|
||||
if (hasPrev()) {
|
||||
possiArray(p_iter) = null
|
||||
solution(pif) = 0
|
||||
pif = prev()
|
||||
} else {
|
||||
return Nil
|
||||
}
|
||||
} else {
|
||||
solution(pif) = possis(0)
|
||||
possiArray(p_iter) = (possis.toSet - possis(0)).toList.sortWith(_<_)
|
||||
if (hasNext()) {
|
||||
pif = next()
|
||||
} else {
|
||||
return checkSol(solution.toList)
|
||||
}
|
||||
}
|
||||
}
|
||||
checkSol(solution.toList)
|
||||
}
|
||||
}
|
||||
|
||||
val f2Str: List[Int] => String = fields => {
|
||||
val sepLine = "+---+---+---+"
|
||||
val sepPoints = Set(2,5,8)
|
||||
val fs: (Int, Int) => String = (i, v) => v.toString.replace("0"," ")+(if (sepPoints.contains(i%9)) "|" else "")
|
||||
sepLine+"\n"+(0 to fields.size-1).map(i => (if (i%9==0) "|" else "")+fs(i,fields(i))+(if (i%9==8) if (sepPoints.contains(i/9)) "\n"+sepLine+"\n" else "\n" else "")).foldRight("")(_+_)
|
||||
}
|
||||
|
||||
val solver = new Solver()
|
||||
|
||||
val riddle = List(3,9,4,0,0,2,6,7,0,
|
||||
0,0,0,3,0,0,4,0,0,
|
||||
5,0,0,6,9,0,0,2,0,
|
||||
0,4,5,0,0,0,9,0,0,
|
||||
6,0,0,0,0,0,0,0,7,
|
||||
0,0,7,0,0,0,5,8,0,
|
||||
0,1,0,0,6,7,0,0,8,
|
||||
0,0,9,0,0,8,0,0,0,
|
||||
0,2,6,4,0,0,7,3,5)
|
||||
|
||||
println("riddle:")
|
||||
println(f2Str(riddle))
|
||||
var solution = solver.solve(riddle)
|
||||
|
||||
println("solution:")
|
||||
println(solution match {case Nil => "no solution!!!" case _ => f2Str(solution)})
|
||||
|
||||
}
|
||||
118
Task/Sudoku/Scala/sudoku-2.scala
Normal file
118
Task/Sudoku/Scala/sudoku-2.scala
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
object SudokuSolver extends App {
|
||||
|
||||
object Solver {
|
||||
var solution = new Array[Int](81)
|
||||
|
||||
val fap: (Int, Int) => Int = (row, col) => (row)*9+col //function array position
|
||||
|
||||
def solve(listOfFields: List[Int]): List[Int] = {
|
||||
solution = listOfFields toArray
|
||||
|
||||
val mRowSubset = new Array[Boolean](81)
|
||||
val mColSubset = new Array[Boolean](81)
|
||||
val mBoxSubset = new Array[Boolean](81)
|
||||
|
||||
def initSubsets: Unit = {
|
||||
for (row <- 0 to 8) {
|
||||
for (col <- 0 to 8) {
|
||||
val value = solution(fap(row, col))
|
||||
if (value != 0)
|
||||
setSubsetValue(row, col, value, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def setSubsetValue(r: Int, c: Int, value: Int, present: Boolean): Unit = {
|
||||
mRowSubset(fap(r, value - 1)) = present
|
||||
mColSubset(fap(c, value - 1)) = present
|
||||
mBoxSubset(fap(computeBoxNo(r, c), value - 1)) = present
|
||||
}
|
||||
|
||||
def computeBoxNo(r: Int, c: Int): Int = {
|
||||
val boxRow = r / 3
|
||||
val boxCol = c / 3
|
||||
return boxRow * 3 + boxCol
|
||||
}
|
||||
|
||||
def isValid(r: Int, c: Int, value: Int): Boolean = {
|
||||
val vVal = value - 1
|
||||
val isPresent = mRowSubset(fap(r, vVal)) || mColSubset(fap(c, vVal)) || mBoxSubset(fap(computeBoxNo(r, c), vVal))
|
||||
return !isPresent
|
||||
}
|
||||
|
||||
def solve(row: Int, col: Int): Boolean = {
|
||||
var r = row
|
||||
var c = col
|
||||
|
||||
if (r == 9) {
|
||||
r = 0
|
||||
c += 1
|
||||
if (c == 9)
|
||||
return true
|
||||
}
|
||||
|
||||
if(solution(fap(r,c)) != 0)
|
||||
return solve(r+1,c)
|
||||
for(value <- 1 to 9)
|
||||
if(isValid(r, c, value)) {
|
||||
solution(fap(r,c)) = value
|
||||
setSubsetValue(r, c, value, true)
|
||||
if(solve(r+1,c))
|
||||
return true
|
||||
setSubsetValue(r, c, value, false)
|
||||
}
|
||||
solution(fap(r,c)) = 0
|
||||
return false
|
||||
}
|
||||
|
||||
def checkSol: Boolean = {
|
||||
initSubsets
|
||||
if ((mRowSubset.exists(_==false)) || (mColSubset.exists(_==false)) || (mBoxSubset.exists(_==false))) return false
|
||||
true
|
||||
}
|
||||
|
||||
initSubsets
|
||||
val ret = solve(0,0)
|
||||
if (ret)
|
||||
if (checkSol) return solution.toList else Nil
|
||||
else
|
||||
return Nil
|
||||
}
|
||||
}
|
||||
|
||||
val f2Str: List[Int] => String = fields => {
|
||||
val f2Stri: List[Int] => String = fields => {
|
||||
val sepLine = "+---+---+---+"
|
||||
val sepPoints = Set(2,5,8)
|
||||
val fs: (Int, Int) => String = (i, v) => v.toString.replace("0"," ")+(if (sepPoints.contains(i%9)) "|" else "")
|
||||
val s = sepLine+"\n"+(0 to fields.size-1).map(i => (if (i%9==0) "|" else "")+fs(i,fields(i))+(if (i%9==8) if (sepPoints.contains(i/9)) "\n"+sepLine+"\n" else "\n" else "")).foldRight("")(_+_)
|
||||
s
|
||||
}
|
||||
val s = fields match {case Nil => "no solution!!!" case _ => f2Stri(fields)}
|
||||
s
|
||||
}
|
||||
|
||||
val elapsedtime: (=> Unit) => Long = f => {val s = System.currentTimeMillis; f; (System.currentTimeMillis - s)/1000}
|
||||
|
||||
var sol = List[Int]()
|
||||
|
||||
val sudokus = List(
|
||||
("riddle used in Ada section:",
|
||||
"394..267....3..4..5..69..2..45...9..6.......7..7...58..1..67..8..9..8....264..735"),
|
||||
("riddle used in Bracmat section:",
|
||||
"..............3.85..1.2.......5.7.....4...1...9.......5......73..2.1........4...9"),
|
||||
("riddle from Groovy section: 4th exceptionally difficult example in Wikipedia: ~80 seconds",
|
||||
"..3......4...8..36..8...1...4..6..73...9..........2..5..4.7..686........7..6..5.."),
|
||||
("riddle used in Ada section with incorrect modifactions - it should fail:",
|
||||
"3943.267....3..4..5..69..2..45...9..6.......7..7...58..1..67..8..9..8....264..735"),
|
||||
("riddle constructed with mess - it should fail too:",
|
||||
"123456789456789123789123456.45..89..6.......72.7...58.31..67..8..9..8....264..735"))
|
||||
|
||||
for (sudoku <- sudokus) {
|
||||
val desc = sudoku._1
|
||||
val riddle = sudoku._2.replace(".","0").toList.map(_.toString.toInt)
|
||||
println(desc+"\n"+f2Str(riddle)+"\n"
|
||||
+"elapsed time: "+elapsedtime(sol = Solver.solve(riddle))+" sec"+"\n"+"solution:"+"\n"+f2Str(sol)
|
||||
+("\n"*2))
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue