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 defs 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
privatemodifier, or - move
hasNoDuplicatesoutside ofvalidate(but remember it would only make sense for it to beprivateif it's in the immediate scope of anobject,classortrait)
The first is easier but in general I would recommend maybe considering if you could resort less to nesting defs. Of course, that's for you to judge.
