8

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
  }
om-nom-nom
  • 62,329
  • 13
  • 183
  • 228
thlim
  • 2,908
  • 3
  • 34
  • 57

1 Answers1

11

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
Community
  • 1
  • 1
senia
  • 37,745
  • 4
  • 88
  • 129