Answer the question
In order to leave comments, you need to log in
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
The Zen of FP is to use functions and values. So just about anything falls into that category.
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 questionAsk a Question
731 491 924 answers to any question