summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-array-ext/mrblib/array.rb
diff options
context:
space:
mode:
authordearblue <[email protected]>2021-12-12 21:28:03 +0900
committerdearblue <[email protected]>2021-12-12 21:28:03 +0900
commit586525f99a982502bda6b0540ae5e1f7ac322168 (patch)
treed059090fb93efd530c2e6e6eb319888c5e43986a /mrbgems/mruby-array-ext/mrblib/array.rb
parent7349902d5bfff7aef08d6f069707b12cc07e0071 (diff)
downloadmruby-586525f99a982502bda6b0540ae5e1f7ac322168.tar.gz
mruby-586525f99a982502bda6b0540ae5e1f7ac322168.zip
Add `Array#{repeated_combination,repeated_permutation}` methods
Ruby 1.9.2 feature. ref: https://docs.ruby-lang.org/ja/3.1.0/method/Array/i/repeated_combination.html ref: https://docs.ruby-lang.org/ja/3.1.0/method/Array/i/repeated_permutation.html
Diffstat (limited to 'mrbgems/mruby-array-ext/mrblib/array.rb')
-rw-r--r--mrbgems/mruby-array-ext/mrblib/array.rb73
1 files changed, 73 insertions, 0 deletions
diff --git a/mrbgems/mruby-array-ext/mrblib/array.rb b/mrbgems/mruby-array-ext/mrblib/array.rb
index d04c11e64..1722a3631 100644
--- a/mrbgems/mruby-array-ext/mrblib/array.rb
+++ b/mrbgems/mruby-array-ext/mrblib/array.rb
@@ -943,4 +943,77 @@ class Array
result
end
+
+ ##
+ # call-seq:
+ # ary.repeated_combination(n) { |combination| ... } -> self
+ # ary.repeated_combination(n) -> enumerator
+ #
+ # A +combination+ method that contains the same elements.
+ def repeated_combination(n, &block)
+ raise TypeError, "no implicit conversion into Integer" unless 0 <=> n
+ return to_enum(:repeated_combination, n) unless block
+ __repeated_combination(n, false, &block)
+ end
+
+ ##
+ # call-seq:
+ # ary.repeated_permutation(n) { |permutation| ... } -> self
+ # ary.repeated_permutation(n) -> enumerator
+ #
+ # A +permutation+ method that contains the same elements.
+ def repeated_permutation(n, &block)
+ raise TypeError, "no implicit conversion into Integer" unless 0 <=> n
+ return to_enum(:repeated_permutation, n) unless block
+ __repeated_combination(n, true, &block)
+ end
+
+ def __repeated_combination(n, permutation, &block)
+ case n
+ when 0
+ yield []
+ when 1
+ i = 0
+ while i < self.size
+ yield [self[i]]
+ i += 1
+ end
+ else
+ if n > 0
+ v = [0] * n
+ while true
+ tmp = [nil] * n
+ i = 0
+ while i < n
+ tmp[i] = self[v[i]]
+ i += 1
+ end
+
+ yield tmp
+
+ tmp = self.size
+ i = n - 1
+ while i >= 0
+ v[i] += 1
+ break if v[i] < tmp
+ i -= 1
+ end
+ break unless v[0] < tmp
+ i = 1
+ while i < n
+ unless v[i] < tmp
+ if permutation
+ v[i] = 0
+ else
+ v[i] = v[i - 1]
+ end
+ end
+ i += 1
+ end
+ end
+ end
+ end
+
+ self
+ end
end