web-dev-qa-db-fra.com

Générer toutes les combinaisons possibles d'un tableau avec une longueur dans une plage donnée

Comment puis-je générer toutes les combinaisons possibles d'éléments d'un tableau avec une longueur dans une plage donnée? Par exemple.:

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

devrait produire un tableau comme:

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

y compris à partir de "abc" (trois caractères) jusqu'à la dernière combinaison possible de ('a'..'f').to_a avec cinq caractères. Je n'ai aucune idée comment faire ça. De l'aide?

24
fschuindt

Array#combination est 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"]]

si vous voulez toutes les combinaisons de taille min à max:

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

Si vous voulez les convertir en chaînes, remplacez simplement .to_a Par .map(&:join).

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

Modifier: pour répondre à l'intention clarifiée d'OP, utilisez repeated_permutation.

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

Vous pouvez modifier ma réponse à votre question précédente de cette façon pour obtenir ce que vous voulez.

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)
2
oldergod

"

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: Excusez la brièveté de ce qui précède, piraté sur un iPad tout en cherchant une autre réponse. Et j'avais tellement tort.

Disons que vous voulez toutes les combinaisons de A à Z pour un maximum de 3 colonnes.

Toutes les combinaisons sont 26 * 26 * 26 = 26 ** 3 = 17576

Permet de soustraire 1 pour 0 points de départ de tableaux = 17575

Nous avons également besoin de variables de mappage, map26 est une recherche de base 26 pour une colonne

map26 = '0123456789abcdefghijklmnop'
map10 = 'abcdefghijklmnopqrstuvwxyz'

Retour à notre combo maximum

17575.to_s(26)
=> "ppp"

Extrayez l'index de 'p' de map26 et mettez-le dans map10:

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

Donc, si vous coupez et coupez le "ppp" ci-dessus, vous obtiendrez un combo maximum de "zzz"

Vous pouvez également voir dans les variables de mappage que "000" mappera sur "aaa"

J'ai modifié le code d'origine pour inclure ces changements.

En ce qui concerne la question d'origine, vous pouvez utiliser D pour contrôler la longueur maximale de la chaîne et jouer avec la valeur de départ de la boucle for pour contrôler la longueur minimale.

2
Emma's Fist