2

This is a follow up to this question: Generate all "unique" subsets of a set (not a powerset)

My problem is the same, but I think there might be a more optimized solution when order of items in the new subsets and across the subsets needs to be preserved.

Example:

[1, 2, 3]

Would result in:

[[1], [2], [3]]
[[1, 2], [3]]
[[1], [2, 3]]
[[1, 2, 3]]
Community
  • 1
  • 1
mbdev
  • 6,343
  • 14
  • 46
  • 63

2 Answers2

3

If I understand it correctly, you want to insert "delimiters" into a list, to partition it. Taking your example, and using the | character to indicate the delimiter,

1 2 3
1 2|3
1|2 3
1|2|3

are the solutions you want.

In a list (I'm calling it a list and not a set because you need the order preserved) of n elements, there are n-1 potential positions for a delimiter. In the example above, there are two positions. In each position, a delimiter might or might not be present.

You can use the binary representation of numbers from 0 to 2^(n-1) - 1 to list all possible arrangements of delimiters. In your example, this'll be number from 0..3.

0:  00
1:  01
2:  10
3:  11
Szabolcs
  • 24,728
  • 9
  • 85
  • 174
  • This has been really helpful. Since I need combinations with exact number of delimiters, I found my problem can also be specialized to this question: http://stackoverflow.com/questions/1851134/generate-all-binary-strings-of-length-n-with-k-bits-set but since I have small sets the function given and filtering out non fitting combinations is good for now. – mbdev Mar 16 '12 at 18:11
2

I've already answered this question for Python, so I quickly ported my solution over to Ruby:

def spannings(lst)
  return enum_for(:spannings, lst) unless block_given?

  yield [lst]
  (1...lst.size).each do |i|
    spannings(lst[i..-1]) do |rest|
      yield [lst[0,i]] + rest
    end
  end
end

p spannings([1,2,3,4]).to_a

See my other answer for a complete explanation of how and why this works.

Community
  • 1
  • 1
Niklas B.
  • 92,950
  • 18
  • 194
  • 224