Calculating Combinations The Cool Way

I recently had to calculate all possible combinations of a set. I needed to calculate combinations of 1..N size, where N is the size of the original set of things. Order inside of the resulting combinations did not matter to me, as I am treating the combinations as true sets.

For example, given the set [A,B,C], I needed to calculate the following combinations:

  • []
  • [A]
  • [B]
  • [C]
  • [AB]
  • [AC]
  • [BC]
  • [ABC]

It dawned on me that a cool way to generate the combinations was to treat the sets (the original set and the resulting combination sets) as bit strings. If the bit corresponding to the member is on, I include the member in the combination.

To explain, I start with the set [A,B,C]. I create a number that has three bits, all on, one for each member of the set. I therefore have the binary number 111 matching [A,B,C]. 111 happens to be 7 in decimal, which is one less than the total number of combinations I require.

Starting with zero, I loop up and including seven (for a total of eight iterations, once for each combo that I want). I convert each iteration count to a binary string, which will give me which bits are on for this combination.

For example, here’s the ruby code:


original_set = [:A, :B, :C]
combinations = []

def create_combo(bit_string, original_set)
  combo = []
  bit_string.split(//).each_with_index do |bit, i|
    combo << original_set[i] if bit == "1"
  end
  combo
end

(2**original_set.size).times do |i|
  bit_string = sprintf("%03b", i)
  combinations << create_combo(bit_string, original_set)
end

require 'pp'
pp combinations

This will print out:

[[], [:C], [:B], [:B, :C], [:A], [:A, :C], [:A, :B], [:A, :B, :C]]

Neat, huh?

I’m sure you can speed this up by checking each bit in the iteration count instead of first converting to a bit string.

3 Responses to “Calculating Combinations The Cool Way”

  1. Semergence » Blog Archive » Calculating Combinations the Erlang Way Says:

    […] you recall, I wrote some Ruby code to calculate combinations of values in lists. I needed to create a list of all combinations of values, where each combination had between 0 and […]

  2. Turbine Says:

    This is great! I created a database of possible combinations, and just run my strings against that to get combinations.

    Is it true this only works for sets with up to 9 members? I don’t believe I can create a binary longer than that. Am I missing something?

  3. Asen’s Random Things and Thoughts Says:

    […] Semergence » Blog Archive » Calculating Combinations The Cool Way Posted in Links, Engineering || […]

Leave a Reply