1

Ok, i've searched the internet for answers and also searched for hours in my ruby programmer but i cant sort this out. I'm writing a script for making all sorts of combinations from elements in an array.

ar = ["a","b","c","d"]

At this point I am able to make these combinations:

["a"],["a","b"],["a","b","c"],["a","b","c","d"],["b"],["b","c"],["b","c","d"],["c"],["c","d"],["d"]

This is OK, but I can't find a way for searching these combinations, for example ["a","c"] or ["a","c","d"] or ["a","d"], etc...

For now my code looks like:

def combinaties(array)
  combinaties = []
  i=0
  while i <= array.length-1
    combinaties << array[i]
    unless i == array.length-1
      array[(i+1)..(array.length-1)].each{|volgend_element|
        combinaties<<(combinaties.last.dup<<volgend_element)
      }
    end
    i+=1
  end
end
5
  • what's your question...? Commented Jan 4, 2012 at 22:02
  • are you looking for permutations? You could try that with the array indexes. Commented Jan 4, 2012 at 22:06
  • 1
    @three Class Array has a permutation method. Commented Jan 4, 2012 at 22:32
  • 2
    Are you looking for a powerset? stackoverflow.com/questions/8533336/… Commented Jan 4, 2012 at 22:36
  • @steenslag yup, could't recall whether it was in Array or not :) Commented Jan 4, 2012 at 23:23

3 Answers 3

9

Functional approach (needs Ruby >= 1.9) to create the powerset of an array (except for the empty element you don't seem to need):

xs = ["a", "b", "c", "d"]
yss = 1.upto(xs.size).flat_map do |n|
  xs.combination(n).to_a
end

#[
#  ["a"], ["b"], ["c"], ["d"],
#  ["a", "b"], ["a", "c"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"],
#  ["a", "b", "c"], ["a", "b", "d"], ["a", "c", "d"], ["b", "c", "d"],
#  ["a", "b", "c", "d"],
#]
Sign up to request clarification or add additional context in comments.

1 Comment

That looks like what I need! Only thing is that I'm stuck with Ruby 1.8.6... It's for a Google SketchUp plugin that I'm working on so upgrading Ruby is not an option. Thanks for the response anyway! Greetings
4

There is a trivial correspondence (bijection) between such combinations and the numbers in [1..(2^m - 1)] (m being the array length).

Consider such a number n. It's binary representation has m digits (including leading zeros). The positions of the digits that are 1 are the indices of the elements in the corresponding combination.

The code would be:

def combinations(array)
  m = array.length
  (1...2**m).map do | n |
    (0...m).select { | i | n[i] == 1 }.map { | i | array[i] }
  end
end

1 Comment

You can use bitwise indexing into integers in Ruby to find out if a certain bit is 1, which leads to simpler code: stackoverflow.com/a/8535241/220147
2

Or in ruby 1.9

%w(a b c d e).combination(3).to_a

will give you all the combinations of size 3.

1 Comment

Same problem here, I'm stuck with Ruby 1.8.6... Thanks for the response!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.