I have tried to convert this Scala function to return a lazy Stream instead of eagerly retrieve all the results and convert them from a Seq to Stream when all the results are present. I have feeling the issue lies in (for (i <- 1 to 9; z <- solve(xs.updated(pos, i), pos)) yield z) toStream.
Any advice is appreciated. Another solution I am looking at is to return a result when it is found. With this solution I probably have only 1 result returned. Thanks
isConflictAt(xs.updated(pos, 0), pos, xs(pos)
is a constraint check function.
def solve(xs : List[Int], pos: Int): Stream[List[Int]] = {
if (!isConflictAt(xs.updated(pos, 0), pos, xs(pos))) {
val pos = xs.indexOf(0)
if (pos < 0) {println(xs); Stream(xs) } else (for (i <- 1 to 9; z <- solve(xs.updated(pos, i), pos)) yield z) toStream
} else Stream.empty
}
for (i <- 1 to 9; z <- solve(???)) yield z
means (1 to 9).flatMap{i => solve(???)}
. See this answer.
To generate lazy result you should make the source (1 to 9
) lazy using (1 to 9).view
or (1 to 9).toStream
.
Try this:
scala> def solve(pos: Int): Stream[List[Int]] = {
| println(pos)
| Stream.fill(3)((1 to pos).map{ _ => util.Random.nextInt}.toList)
| }
solve: (pos: Int)Stream[List[Int]]
scala> for{
| i <- (1 to 9).toStream
| z <- solve(i)
| } yield z
1
res1: scala.collection.immutable.Stream[List[Int]] = Stream(List(-1400889479), ?)
scala> res1.force
2
3
4
5
6
7
8
9
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With