Saturday, 25 April 2009

My first attempt at writing Scala code

My first attempt at writing Scala code.

Here are a couple of links that were useful:
http://www.codecommit.com/blog/scala/scala-collections-for-the-easily-bored-part-2

And here is a link to how a solver _should_ be written when my functional programming gets a little better.
http://scala.sygneca.com/code/sudoku

The following is a Soduku solver


package soduku

object Main {

def main(args: Array[String]) = {
var list = List(
List(4,0,0, 0,0,1, 6,0,0,),
List(0,0,0, 3,9,0, 0,0,0,),
List(0,0,0, 0,8,0, 7,3,2,),

List(3,0,0, 0,0,0, 1,2,0,),
List(0,0,6, 0,0,0, 5,0,0,),
List(0,7,2, 0,0,0, 0,0,8,),

List(2,5,9, 0,7,0, 0,0,0,),
List(0,0,0, 0,4,3, 0,0,0,),
List(0,0,4, 8,0,0, 0,0,1,),
)
val answers = Main.solve(0,0,list)
answers.foreach(A => Main.printMe(A))
}

//----------------------- Checking row, col & box ------------------
def isInRow(p : List[Int], toLookFor : Int) : boolean = {
p.contains(toLookFor)
}

def isInColumn(p : List[List[Int]], columnNumber : Int, toLookFor : Int) : boolean = {
val columnList = p.map( A => A(columnNumber) )
isInRow(columnList, toLookFor)
}


def isInBox(p : List[List[Int]], rowNumber : Int, columnNumber : Int, toLookFor : Int) : boolean = {
val colStart = Math.floor(columnNumber / 3).asInstanceOf[Int]
val rowStart = Math.floor(rowNumber / 3).asInstanceOf[Int]
val correctRowGroup = List ( p(rowStart*3) , p(rowStart*3 + 1) , p(rowStart*3 + 2) )

val boxAsList = List (
correctRowGroup(0)(colStart*3),
correctRowGroup(0)(colStart*3 + 1),
correctRowGroup(0)(colStart*3 + 2),
correctRowGroup(1)(colStart*3),
correctRowGroup(1)(colStart*3 + 1),
correctRowGroup(1)(colStart*3 + 2),
correctRowGroup(2)(colStart*3),
correctRowGroup(2)(colStart*3 + 1),
correctRowGroup(2)(colStart*3 + 2)
)
return isInRow(boxAsList, toLookFor)
}

def isOkToPutHere(p : List[List[Int]], rowNumber : Int, columnNumber : Int, toLookFor : Int) : boolean = {
(p(rowNumber)(columnNumber) == 0) &&
!(isInRow(p(rowNumber), toLookFor)
|| isInColumn(p, columnNumber, toLookFor)
|| isInBox(p, rowNumber, columnNumber, toLookFor))
}


//----------------------- Finished Checking row, col & box ------------------

def solve(x : Int, y : Int, toFill : List[List[Int]]) : List[List[List[Int]]] = {
if (x == 9) solve(0, y+1, toFill)
else if (y == 9) List(toFill)
else if (toFill(x)(y) != 0) solve(x+1, y, toFill)
else {
val anotherDigit = (1 to 9).flatMap( A => {
if (isOkToPutHere(toFill, x, y, A)) {
val rowToFill = toFill(x)
val v = toFill.slice(0, x) :::
(rowToFill.slice(0, y) ::: A :: rowToFill.slice(y+1, 9)) ::
toFill.slice(x+1, 9)
solve(x, y, v)
} else {
Nil
}
}
)
anotherDigit.projection.elements.toList
}
}

def printMe( toFill : List[List[Int]]) = {
println("Solution:")
toFill.foreach( A => {
val line = "[" + printLine(A) + "]"
println( line )
})
}

def printLine(toPrint : List[Int]) : String = {
if (toPrint.length == 1) "" + toPrint.head
else if (toPrint.length % 3 == 1) toPrint.head + ", " + printLine(toPrint.tail)
else toPrint.head + "," + printLine(toPrint.tail)
}

}

No comments:

Post a comment