HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

How idiomatic is this Scala 36 Cube Solver?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thisidiomaticscalacubehowsolver

Problem

I've written a short program to find solutions to the 36 Cube puzzle.

I'm trying to break away from my normal Java / imperative style, and would like some feedback on how I'm doing.

Puzzle.scala

package cube36

/**
 * An immutable class representing the state of a 36 Cube puzzle
 */
case class CubePuzzle(val board: Board, val availablePieces: List[Piece]) {

  /**
   * Add a piece to this puzzle, to create new instance of the puzzle
   * @param rowNum row to add piece to
   * @param colNum column to add piece to
   * @param piece piece to add
   * @param checkSuitable check if the position will accept this piece (default true if omitted)
   * @return a new puzzle instance, with the specified piece added
   */
  def addPiece(rowNum: Int, colNum: Int, piece: Piece, checkSuitable: Boolean = true): CubePuzzle = {
    val newBoard = board.addPiece(rowNum, colNum, piece,checkSuitable)
    CubePuzzle(newBoard, availablePieces.filterNot(_ == piece))
  }

  /**
   * Find solutions to the puzzle which satisfy the rules
   * @param solutionsSoFar
   * @return a list of all valid solutions
   */
  def solve(solutionsSoFar: List[Board]=List[Board]()): List[Board] = {
    if (this.availablePieces.size == 0) this.board :: solutionsSoFar
    else {
      val nextPiece = availablePieces.head
      val availableSpots = board.spaces.filter(space => board.suitable(space, nextPiece))
      val sols = for (spot = 1,"Piece size out of range")

  override def toString: String = colour.toString().head.toString + size.toString
}


Board.scala

```
package cube36

case class Board(val placedPieces: IndexedSeq[IndexedSeq[Option[Piece]]] /rows of cols/ ) {

val row1Heights = ListInt
val row2Heights = ListInt
val row3Heights = ListInt
val row4Heights = ListInt
val row5Heights = ListInt
val row6Heights = ListInt
val contours = List[List[Int]](row1Height

Solution

Puzzle.scala

case class CubePuzzle(val board: Board, val availablePieces: List[Piece])


Case classes don't need "val" before field names.

def solve(solutionsSoFar: List[Board]=List[Board]()): List[Board] =


More idiomatic is Nil instead of List[Board](). Although sometimes I use List.empty[Board] in case I change the collection type (Nil is only available on List)

if (this.availablePieces.size == 0) this.board :: solutionsSoFar


Instead, how about

availablePieces match {
  case Nil => board :: solutionsSoFar
  case nextPiece :: tail => ...


Also, I suspect the for loop in solve() can be rewritten so that you do not need to call flatten.

Board.scala

val unsuitable = ...


This seems backward, why not just return

spaceEmpty && rightHeight && !colourAlreadyInCol && !colourAlreadyInRow

Code Snippets

case class CubePuzzle(val board: Board, val availablePieces: List[Piece])
def solve(solutionsSoFar: List[Board]=List[Board]()): List[Board] =
if (this.availablePieces.size == 0) this.board :: solutionsSoFar
availablePieces match {
  case Nil => board :: solutionsSoFar
  case nextPiece :: tail => ...
val unsuitable = ...

Context

StackExchange Code Review Q#22865, answer score: 3

Revisions (0)

No revisions yet.