I'm solving a problem and I got this:
ant : scala.collection.mutable.ListBuffer[Set[Int]] = ListBuffer(Set(), Set(0), Set(0), Set(1), Set(2), Set(1), Set(3,4), Set(5, 6), Set(7))
The Sets in the ListBuffer represent dependencies, for example: ant(1) is the Set(0), which means that ant(1) depends of ant(0) which is the Set(). The same with the others, another example: ant(7) is the Set(5, 6) which means that ant(7) depends of ant(5) and ant(6).
What I need to obtain is a new ListBuffer[Set[Int]] with all the dependencies between the Sets without repetitions, for example: ant(6) depends of ant(3) and ant(4), at the same time ant(3) depends of ant(1) and ant(4) depends of ant(2), and ant(1) and ant(2) depend of ant(0), so the result with all the dependencies in ant(6) is: Set(3,4,1,2,0)
So the result of the initial ListBuffer should be:
solution : scala.collection.mutable.ListBuffer[Set[Int]] = ListBuffer(Set(), Set(0), Set(0), Set(1,0), Set(2,0), Set(1,0), Set(3,4,1,2,0), Set(5,6,1,3,4,0,2), Set(7,5,6,1,0,4,3,2))
Which is the best way to do it?
Thanks.
This is definitely the wrong data structure for what you are trying to represent. To get the result you seek you'll have to go through a tortured sequence of steps even more convoluted than the data structure itself.
So here's where we start.
import collection.mutable.ListBuffer
val ant: ListBuffer[Set[Int]] = ListBuffer(Set(), Set(0), Set(0), Set(1), Set(2),
Set(1), Set(3,4), Set(5, 6), Set(7))
Now we need to add the sub-dependencies to each of the current Sets of dependencies. Since these are Set
s of Int
s, the order of presentation doesn't matter.
ant.map(_.flatMap(x => ant(x) + x))
// ListBuffer(Set(), Set(0), Set(0), Set(0, 1), Set(0, 2), Set(0, 1), Set(1, 3, 2, 4), Set(5, 1, 6, 3, 4), Set(5, 6, 7))
Now we need to repeat that until the new result is the same as the previous result. A Stream
iterator will set up the repetitions and we'll dropWhile
each element is different from the previous.
// a ListBuffer Stream
val lbStrm: Stream[ListBuffer[Set[Int]]] =
Stream.iterate[ListBuffer[Set[Int]]](ant)(_.map(_.flatMap(x => ant(x) + x)))
// grab the first one after the results settle
lbStrm.zipWithIndex.dropWhile{case (lb,x) => lb != lbStrm(x+1)}.head._1
// ListBuffer(Set(), Set(0), Set(0), Set(0, 1), Set(0, 2), Set(0, 1), Set(0, 1, 2, 3, 4), Set(0, 5, 1, 6, 2, 3, 4), Set(0, 5, 1, 6, 2, 7, 3, 4))
Not pretty, but doable. It would be much better to redesign that starting data structure.