2012-11-27 2 views
0

Je suis en train d'écrire une extension Array qui fait quelque chose comme ceci:Permutations d'un tableau où les éléments sont répétés un certain nombre de fois

Je l'appelle comme ceci:

%w[eggs bacon sausage].with_every_possibiity_of_multiples(2)

Et il me donne ces:

[ 
    %w[eggs, bacon, sausage], 
    %w[eggs, eggs, bacon, sausage], 
    %w[eggs, bacon, bacon, sausage], 
    %w[eggs, bacon, sausage, sausage], 
    %w[eggs, eggs, bacon, bacon, sausage], 
    %w[eggs, eggs, bacon, bacon, sausage, sausage], 
    ] 

Espérons que c'est clair ce qui se passe ici. Si je l'avais appelé avec un argument de 3 au lieu de 2, j'aurais eu un tableau de 9 éléments, l'un d'entre eux étant %w[eggs, eggs, eggs, bacon, sausage].

J'ai du mal à trouver comment écrire ceci. Aucune suggestion?

+1

Quelque chose de mal dans votre méthode dite «with_every_posssibiity_of_multiples (arg). Post ce code de méthode – dealer

+1

BTW, * permutation * est le mauvais terme; * La combinaison * est plus proche –

+1

-1. Votre question n'est pas claire. Je ne peux pas obtenir la règle. Pourquoi «% w [oeufs, bacon, bacon, saucisse, saucisse]» et «% w [oeufs, œufs, bacon, saucisse, saucisse]» ne sont pas dans le tableau? En premier lieu, pourquoi avez-vous des virgules dans la notation '% w'? – sawa

Répondre

1

Comme @sawa souligne, vous avez probablement mélangé vos résultats vers le haut. Je suppose que le passage 2 vous obtient 8 éléments, pas 6, et le passage 3 vous obtient 27, et non 9.

Vous pouvez faire un bon usage de Array#repeated_combination pour générer le nombre de fois que vous voulez répéter chaque élément:

class Array 
    def with_every_possibility_of_multiples(n) 
    (1..n).to_a.repeated_permutation(size).map do |repeats| 
     zip(repeats).flat_map{|elem, nb| [elem] * nb} 
    end 
    end 
end 

food = %w[eggs bacon sausage] 
food.with_every_possibility_of_multiples(2) # => 
[["eggs", "bacon", "sausage"], ["eggs", "bacon", "sausage", "sausage"], ["eggs", "bacon", "bacon", "sausage"], 
["eggs", "bacon", "bacon", "sausage", "sausage"], 
["eggs", "eggs", "bacon", "sausage"], 
["eggs", "eggs", "bacon", "sausage", "sausage"], 
["eggs", "eggs", "bacon", "bacon", "sausage"], 
["eggs", "eggs", "bacon", "bacon", "sausage", "sausage"]] 

food.with_every_possibility_of_multiples(3) # => 
[["eggs", "bacon", "sausage"], 
["eggs", "bacon", "sausage", "sausage"], 
["eggs", "bacon", "sausage", "sausage", "sausage"], 
["eggs", "bacon", "bacon", "sausage"], 
["eggs", "bacon", "bacon", "sausage", "sausage"], 
["eggs", "bacon", "bacon", "sausage", "sausage", "sausage"], 
["eggs", "bacon", "bacon", "bacon", "sausage"], 
["eggs", "bacon", "bacon", "bacon", "sausage", "sausage"], 
["eggs", "bacon", "bacon", "bacon", "sausage", "sausage", "sausage"], 
["eggs", "eggs", "bacon", "sausage"], 
["eggs", "eggs", "bacon", "sausage", "sausage"], 
["eggs", "eggs", "bacon", "sausage", "sausage", "sausage"], 
["eggs", "eggs", "bacon", "bacon", "sausage"], 
["eggs", "eggs", "bacon", "bacon", "sausage", "sausage"], 
["eggs", "eggs", "bacon", "bacon", "sausage", "sausage", "sausage"], 
["eggs", "eggs", "bacon", "bacon", "bacon", "sausage"], 
["eggs", "eggs", "bacon", "bacon", "bacon", "sausage", "sausage"], 
["eggs", "eggs", "bacon", "bacon", "bacon", "sausage", "sausage", "sausage"], 
["eggs", "eggs", "eggs", "bacon", "sausage"], 
["eggs", "eggs", "eggs", "bacon", "sausage", "sausage"], 
["eggs", "eggs", "eggs", "bacon", "sausage", "sausage", "sausage"], 
["eggs", "eggs", "eggs", "bacon", "bacon", "sausage"], 
["eggs", "eggs", "eggs", "bacon", "bacon", "sausage", "sausage"], 
["eggs", "eggs", "eggs", "bacon", "bacon", "sausage", "sausage", "sausage"], 
["eggs", "eggs", "eggs", "bacon", "bacon", "bacon", "sausage"], 
["eggs", "eggs", "eggs", "bacon", "bacon", "bacon", "sausage", "sausage"], 
["eggs", "eggs", "eggs", "bacon", "bacon", "bacon", "sausage", "sausage", "sausage"]] 

Notez que repeated_permutation est nouveau pour Ruby 1.9.2. Vous pouvez require 'backports' dans les versions antérieures, ou utiliser une version plus laide à l'aide product:

# ... 
(1..n).to_a.product(*[(1..n).to_a] * (size-1)).map do |repeats| 
# ... 
0

Vous pouvez essayer cette méthode de permutation intégrée:

%w[eggs bacon sausage].permutation(2).to_a 
Questions connexes