J
J
jdev2012-08-01 10:47:43
Scala
jdev, 2012-08-01 10:47:43

Does the solution fit the functional style of programming?

Good day to all.

I'm trying to learn the zen of FP and as an exercise I wrote a program in scala to find a way for the knight to bypass the chessboard. Guru FP, tell me, does this solution correspond to the functional approach?

def possibleSteps(pos: (Int, Int)) =
  for (x <- -2 to 2; y <- -2 to 2; if x != 0 && y != 0 && scala.math.abs(x) != scala.math.abs(y))
  yield (pos._1 + x, pos._2 + y)

def canStep(path: List[(Int, Int)], pos: (Int, Int)) =
  if (path.length == 0) true
  else possibleSteps(path.head).contains(pos)

def nextSteps(available: scala.List[(Int, Int)], path: scala.List[(Int, Int)]): List[(Int, Int)] =
  for (pos <- available; if canStep(path, pos)) yield pos

def getPath(path: List[(Int, Int)], available: List[(Int, Int)]): List[(Int, Int)] =
  if (available.size == 0)
    path
  else
    nextSteps(available, path).foldLeft(List[(Int, Int)]()) (
      (found, e) => found match {
          case Nil => getPath(e :: path, available filter { _ != e })
          case lst: List[(Int, Int)] => lst
        }
    )

def generatePositions(side: Int) = for (x <- Range(0, side); y <- Range(0, side)) yield (x, y)

println(getPath(List(), generatePositions(5).toList))


In particular, I have doubts about the following points:
1) The implementation of possibleSteps
2) Is foldLeft applicable in this case? What are the alternatives (I couldn't think of anything else to eliminate the search for all possible paths)?
3) The general style of writing (formatting) - I understand that this is highly dependent on the language and subjective preferences, but maybe there are some generally accepted patterns?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Arthur, 2012-08-01
@ArthurG

The Zen of FP is to use functions and values. So just about anything falls into that category.

S
shock_one, 2012-09-16
@shock_one

No assignments? There is not. Vars too. So it's functional. I must say, the devil will break his leg in your algorithm - I still haven’t fully figured out how it works, but I could redo what I could. It became even more confusing, but shorter.

def canStep(path: List[(Int, Int)], pos: (Int, Int)) =
  if (path.length == 0) true
  else List((pos._1 - path.head._1).abs, (pos._2 - path.head._2).abs).filter(_ < 3).sum == 3

def getPath(path: List[(Int, Int)], available: List[(Int, Int)]): List[(Int, Int)] =
  if (available.size == 0)
    path
  else
    available.filter(canStep(path, _)).foldLeft(List[(Int, Int)]()) {
      (found, e) => found match {
        case Nil => getPath(e :: path, available.filter(_ != e))
        case lst: List[(Int, Int)] => lst
      }
    }

def generatePositions(side: Int) = for (x <- 0 until side; y <- 0 until side) yield (x, y)

println(getPath(List(), generatePositions(5).toList))

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question