0

I have a challenge, im trying to write a method that takes in an array and returns the subset and permutation of twos, including the initial array. How do I check for particular patterns in the array. For example, given this array:

[a,b,c]

subset return will be:

[a,b,c,], [a,b], [b,c], [c,a]

and I also need to check if each subset contains a particular letter. Here's my code:

def conflict_free?(a)
  return a.permutation(2).to_a
end
8
  • What do you have so far? Commented Feb 14, 2012 at 22:51
  • def conflict_free?(a) return a.permutation(2).to_a end Commented Feb 14, 2012 at 22:52
  • Sergio Tulentsev, i still not really good with ruby, but this doesnt even give me any result Commented Feb 14, 2012 at 22:55
  • possible duplicate of Find all subsets of size N in an array using Ruby Commented Feb 14, 2012 at 23:08
  • a.permutation(2) returns [a,b], etc but also [b,a], etc in your example you don't have the switched permutations, did you still want those ? Commented Feb 15, 2012 at 2:19

2 Answers 2

2

Here's how to get the subsets you're looking for:

def subsets(a)
  2.upto(a.length).flat_map {|n| a.combination(n).to_a}
end

irb(main):023:0> subsets(["a", "b", "c"])
=> [["a", "b"], ["a", "c"], ["b", "c"], ["a", "b", "c"]]

Anything else you want, you'll have to edit your question and provide more detail.

Sign up to request clarification or add additional context in comments.

4 Comments

The method needs to be 2.upto(a.length).flat_map {|n| a.combination(n).to_a}
@KassymDorsel You are correct. My local version had it, not sure how it got dropped. Fixed.
With regards to speed the following are better : 2.upto(a.length-1).flat_map {|n| a.combination(n).to_a}<<a or [a] + 2.upto(a.length-1).flat_map {|n| a.combination(n).to_a}
99% of the time I'll opt for simpler syntax over shaving a few milliseconds. In fact, if I was certain it would always be a 3-length array, I'd opt for your first solution, or even a.combination(3).to_a.
0

Here is a very compact and fast solution :

def conflict(a)
  a.combination(2).to_a << a
end

>> [["a", "b"], ["a", "c"], ["b", "c"], ["a", "b", "c"]]

If you did want the initial array at the beginning you sacrificing a fair bit of speed. Nevertheless the best way to do it :

def conflict(a)
  temp = [a]
  a.combination(2).each { |com| temp << com}
  temp
end

>> [["a", "b", "c"], ["a", "b"], ["a", "c"], ["b", "c"]]

If the input is not 3 then this will work :

def conflict(a)
  temp = []
  2.upto(a.size-1) {|i| temp += a.combination(i).to_a}
  temp << a
end

The initial array can be added at the beginning or end. Above it's at the end.

2 Comments

Works for arrays of size 3. OP didn't mention whether there could be other sizes.
True. I've included another version that satisfies for all sizes.

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.