Search code examples
rubyerlangsubsetpowerset

Generate a powerset of a set without keeping a stack in Erlang or Ruby


I would like to generate a powerset of a rather big set (about 30-50 elements) and I know that it takes 2^n to store the powerset.

Is it possible to generate one subset at a time?

I.e. generate a powerset of a set with iterations, saving each generated subset to disk/database, removing it from the stack/memory and only then continuing to generate other subsets?

Unfortunately I have failed to modify Erlang and Ruby examples to my needs.


Solution

  • Edit: Added the enumerator (as @Jörg W Mittag) if no block is given.

    class Array
      def powerset
        return to_enum(:powerset) unless block_given?
        1.upto(self.size) do |n|
          self.combination(n).each{|i| yield i}
        end
      end
    end
    # demo
    ['a', 'b', 'c'].powerset{|item| p item} # items are generated one at a time
    ps = [1, 2, 3, 4].powerset # no block, so you'll get an enumerator 
    10.times.map{ ps.next } # 10.times without a block is also an enumerator
    

    Output

    ["a"]
    ["b"]
    ["c"]
    ["a", "b"]
    ["a", "c"]
    ["b", "c"]
    ["a", "b", "c"]
    [[1], [2], [3], [4], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]