Project

General

Profile

Actions

Feature #21564

open

Extend permutation, repeated_permutation, combination and repeated_combination argument

Added by toy (Ivan Kuchin) about 22 hours ago. Updated about 12 hours ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:123184]

Description

When using functions permutation, repeated_permutation, combination and repeated_combination, often one needs not one, but multiple permutation/combination sizes. Currently all functions accept one Integer argument (for permutation it is optional and defaults to array size), and it would be more powerful if it would accept also a range or a Enumerable:

a = [1, 2, 3]

a.permutation(1..3).to_a # => [[1], [2], [3],
                         #     [1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2],
                         #     [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]

a.permutation([1, 3]).to_a # => [[1], [2], [3],
                           #     [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]

a.permutation([3, 1]).to_a # => [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1],
                           #     [1], [2], [3]]

a.repeated_permutation([2, 1]).to_a # => [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3],
                                    #     [1], [2], [3]]

a.combination(1..3).to_a # => [[1], [2], [3],
                         #     [1, 2], [1, 3], [2, 3],
                         #     [1, 2, 3]]

a.repeated_combination(1..3).to_a # => [[1], [2], [3],
                                  #     [1, 1], [1, 2], [1, 3], [2, 2], [2, 3], [3, 3],
                                  #     [1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 2, 2], [1, 2, 3], [1, 3, 3], [2, 2, 2], [2, 2, 3], [2, 3, 3], [3, 3, 3]]

Ruby code to enhance current permutation would be:

class Array
  alias_method :original_permutation, :permutation

  def permutation(counts, &block)
    return to_enum(__method__, counts) unless block

    if counts.is_a?(Enumerable)
      counts.each do |count|
        original_permutation(count, &block)
      end
    else
      original_permutation(counts, &block)
    end
  end
end

Updated by nobu (Nobuyoshi Nakada) about 12 hours ago

I'm not sure whether this is a natural extension of permutation.

And why not array.permutation(count1, count2, count3)?
Is it important to support Range without splatting?

Updated by mame (Yusuke Endoh) about 12 hours ago

When proposing new features, I strongly recommend writing a use case. It should be as simple and relatable as possible, but if that is difficult, a concrete example that you are actually facing now and that demonstrates general applicability is acceptable. Appealing to conceptual benefits like "powerful" is weak.

Actions

Also available in: Atom PDF

Like0
Like0Like0