[ruby-core:123214] [Ruby Feature#21564] Extend permutation, repeated_permutation, combination and repeated_combination arguments
From:
duerst via ruby-core <ruby-core@...>
Date:
2025-09-11 04:53:01 UTC
List:
ruby-core #123214
Issue #21564 has been updated by duerst (Martin D=FCrst).
I don't think this is necessary. It's better to keep different aspects of a=
calculation separate by using separate methods (building blocks) and combi=
ning them to achieve a goal. As an example, your
```a.permutation(*1..3).to_a```
can easily be written as
```(1..3).flat_map { |i| a.permutation(i).to_a }```.
(Please note that flat_map is already a combination of two methods, but thi=
s was introduced because this combination is really frequent, contrary to y=
ours.)
----------------------------------------
Feature #21564: Extend permutation, repeated_permutation, combination and r=
epeated_combination arguments
https://bugs.ruby-lang.org/issues/21564#change-114544
* Author: toy (Ivan Kuchin)
* Status: Open
----------------------------------------
When using functions `permutation`, `repeated_permutation`, `combination` a=
nd `repeated_combination`, often one needs not one, but multiple permutatio=
n/combination sizes. Currently all functions accept one Integer argument (f=
or `permutation` it is optional and defaults to array size), and it would b=
e more powerful (not require iteration of lengths and possibly flattening) =
if it would accept multiple lengths:
```ruby
a =3D [1, 2, 3]
a.permutation(*1..3).to_a # =3D> [[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 # =3D> [[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 # =3D> [[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 # =3D> [[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 # =3D> [[1], [2], [3],
# [1, 2], [1, 3], [2, 3],
# [1, 2, 3]]
a.repeated_combination(*1..3).to_a # =3D> [[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]]
# find right combination of letters
[*'a'..'z'].repeated_permutation(*3..6).find do |chars|
correct_combination?(chars)
end
# na=EFve knapsack solution
def max_knapsack_value(items, weight_max)
items.combination(*1..items.length)
.map{ |items| [items.sum(&:weight), items.sum(&:value)] }
.reject{ |weight_sum, _| weight_sum > weight_max }
.max_by{ |_, value_sum| value_sum }
&.last || 0
end
```
Hack in code to enhance current methods would be:
```ruby
class Array
%i[
combination
permutation
repeated_combination
repeated_permutation
].each do |method_name|
alias_method "original_#{method_name}", method_name
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{method_name}(*counts, &block)
return to_enum(__method__, *counts) unless block
counts.each do |count|
original_#{method_name}(count, &block)
end
end
RUBY
end
end
```
--=20
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.rub=
y-lang.org/