I am trying to validate a Soduko board. my input is of type Any, so first, I want to change that to Int. and validate that, I write the following code but it can not return the true result and return some error. how can I handle the problem of code? validate method comprised of two other method, one for convert Any to Int and another for validate Sudoko board.
def validate(lines: Array[Option[Any]]*): Boolean = {
object BoardParser {
/**
* Parse a Sudoku board from varargs
* Board needs to have 9 rows, 9 columns & all Int or Long values for non-empty cells, to be accepted
*
* @param board Variable number of optional arrays
* @return A 2D Int array representing the basic Sudoku board
*/
def getValidBoard(board: Array[Option[Any]]*): Array[Array[Int]] = {
def validateBoard() = {
if (board.length != 9 || board.transpose.length != 9) {
throw new IllegalArgumentException("Board must be a 2D array of size 9x9")
} else if (!board.forall(isAllNumbers)) {
throw new IllegalArgumentException("Board must contain only Int or Long values")
}
}
validateBoard()
board.map(toNumbers).toArray
}
private def isAllNumbers(line: Array[Option[Any]]) = {
line.forall {
case Some(_: Int) => true
case Some(_ : Long) => true
case None => true
case _ => false
}
}
private def toNumbers(line: Array[Option[Any]]) = {
line.map {
case Some(x: Int) => x
case Some(x: Long) => x.toInt
case None => 0
case _ => throw new IllegalArgumentException
}
}
}
val valid_board = getValidBoard(lines)
def new_validate(board: Array[Array[Int]]): Boolean = {
lazy val rowsValid = board.forall(hasNoDuplicates)
lazy val columnsValid = board.transpose.forall(hasNoDuplicates)
lazy val cellsValid = squaresHaveNoDuplicates(board)
rowsValid && columnsValid && cellsValid
}
private def hasNoDuplicates(line: Array[Int]) = line.distinct.count(1 to 9 contains _) == line.count(_ != 0)
private def squaresHaveNoDuplicates(matrix: Array[Array[Int]]) = {
val rowBlocks = matrix.grouped(3).toArray
val transposed = rowBlocks.map(_.transpose)
val squares = transposed.map(_.grouped(3).toArray)
val squaresFlattened = squares.map(_.map(_.flatten))
squaresFlattened.forall(_.forall(hasNoDuplicates))
}
return new_validate(valid_board)
CodePudding user response:
You are declaring hasNoDuplicates
inside a def
. private
is a valid modifier only within the immediate scope of an object
, class
or trait
. Nested def
s will anyway be visible exclusively within the scope of the outer def
itself, so private
wouldn't really make sense there. You can choose to either:
- remove the
private
modifier, or - move
hasNoDuplicates
outside ofvalidate
(but remember it would only make sense for it to beprivate
if it's in the immediate scope of anobject
,class
ortrait
)
The first is easier but in general I would recommend maybe considering if you could resort less to nesting def
s. Of course, that's for you to judge.