Подтвердить что ты не робот

Создание всех возможных комбинаций массива с длиной в заданном диапазоне

Как я могу генерировать все возможные комбинации элементов массива с длиной в заданном диапазоне? Например:.

('a'..'f').to_a.all_possibilities(3, 5)

должен создать массив вроде:

['abc', 'abd', 'abe', 'abf', ..., 'abcde', 'abcdf', 'abcda', ...]

включая от "abc" (три символа) до последней возможной комбинации ('a'..'f').to_a с длиной в пять символов. Я не знаю, как это сделать. Любая помощь?

4b9b3361

Ответ 1

Array#combination - stdlib:

[1] pry(main)> a = ('a'..'f').to_a
=> ["a", "b", "c", "d", "e", "f"]
[2] pry(main)> a.combination(3).to_a
=> [["a", "b", "c"],
 ["a", "b", "d"],
 ["a", "b", "e"],
 ["a", "b", "f"],
 ["a", "c", "d"],
 ["a", "c", "e"],
 ["a", "c", "f"],
 ["a", "d", "e"],
 ["a", "d", "f"],
 ["a", "e", "f"],
 ["b", "c", "d"],
 ["b", "c", "e"],
 ["b", "c", "f"],
 ["b", "d", "e"],
 ["b", "d", "f"],
 ["b", "e", "f"],
 ["c", "d", "e"],
 ["c", "d", "f"],
 ["c", "e", "f"],
 ["d", "e", "f"]]

если вы хотите, чтобы все комбинации с размером min были максимальными:

(min..max).flat_map{|size| a.combination(size).to_a }

Если вы хотите, чтобы они были преобразованы в строки, просто замените .to_a на .map(&:join).

Ответ 2

(3..5).flat_map{|n| ('a'..'f').to_a.combination(n).map(&:join)}

Изменить: чтобы выполнить уточненное намерение OP, используйте repeated_permutation.

(3..5).flat_map{|n| ('a'..'f').to_a.repeated_permutation(n).map(&:join)}

Ответ 3

Вы можете изменить свой ответ на свой предыдущий вопрос таким образом, чтобы получить то, что вы хотите.

class Array
  def all_possibilities(from, to)
    (from..to).flat_map do |i|
      if i < size
        permutation(i).to_a 
      else
        permutation(to - i).flat_map do |e|
          (self + e).permutation.to_a
        end
      end
    end.map(&:join)
  end
end

array = ["F", "E", "R", "N", "A", "D", "O"]
array.all_possibilities(3, 8)

Ответ 4

`

D = length of array
N = number of possible values. i.e a-z = 26
possible combinations = N ^ D
array = [possible values]

map26 = '0123456789abcdefghijklmnop'
map10 = 'abcdefghijklmnopqrstuvwxyz'

combo = '' 
for 0...N ** D do |i|
  i.to_s(D).split(//).each do |v|  
    combo += map10[map26.index(v)].chr
  end
  puts combo
  combo = ''
end

`

EDIT: Извините краткость выше, взломали ее на iPad, просматривая другой ответ. И я был так неправ.

Предположим, вы хотите, чтобы все комбинации из a-z использовались для трех столбцов.

Все комбинации: 26 * 26 * 26 = 26 ** 3 = 17576

Позволяет вычесть 1 для 0 начальных точек массивов = 17575

Также нам нужны переменные отображения, map26 - это базовый поиск 26 для одного столбца

map26 = '0123456789abcdefghijklmnop'
map10 = 'abcdefghijklmnopqrstuvwxyz'

Вернуться к нашей максимальной комбо

17575.to_s(26)
=> "ppp"

Извлеките индекс 'p' из map26 и поместите его в map10:

map10[map26.index('p')]   (add .chr for ruby ~ 1.8)
=> "z"

Итак, если вы нарезаете и кубите "ppp" выше, вы получите максимальную комбинацию "zzz"

Вы также можете видеть из переменных отображения, что "000" будет отображаться на "aaa"

Я изменил исходный код, чтобы включить эти изменения.

В отношении исходного вопроса вы можете использовать D для управления максимальной длиной строки и играть со стартовым значением цикла for для управления минимальной длиной.