Permutations avec des articles indiscernables

12

Étant donné une liste d'entiers, affichez le nombre de permutations des entiers, les permutations indiscernables étant comptées une fois. S'il y a des nentiers et que chaque groupe de nombres indiscernables a une longueur n_i, c'estn! / (n_1! * n_2! * ...)

Règles

  • L'entrée sera une forme de liste comme arguments d'une fonction ou du programme avec 1 à 12 entiers non négatifs.

  • La sortie sera l'impression ou le retour du nombre de permutations comme décrit ci-dessus.

  • Pas de failles standard ni de fonctions intégrées (génération de permutations, combinaisons, etc.). Les factoriels sont autorisés.

Cas de test

Contributions:

1, 3000, 2, 2, 8
1, 1, 1
2, 4, 3, 2, 3, 4, 4, 4, 4, 4, 1, 1

Les sorties:

60
1
83160
qwr
la source
quand vous dites non intégré, cela inclut-il ce que j'ai fait lorsque j'ai utilisé un intégré pour générer toutes les permutations?
Maltysen
1
Cela ressemble en grande partie à Calculer le coefficient multinomial . Le fait de compter des entrées identiques pour l'entrée le rend-il suffisamment différent pour ne pas être dupe?
xnor
@xnor bien ici, vous devez réellement compter les doublons, donc ce n'est pas aussi simple, je suppose. L'autre consiste à brancher des valeurs à peu près directement.
qwr
@Maltysen malheureusement oui, je devrai mettre à jour la question
qwr
1
@LuisMendo Oui, mais cela ne devrait pas faire de différence pour autant que je puisse l'imaginer
qwr

Réponses:

6

Python, 48 octets

f=lambda l:l==[]or len(l)*f(l[1:])/l.count(l[0])

Une implémentation récursive.

Dans la formule, n! / (n_1! * n_2! * ...)si nous supprimons le premier élément (disons que c'est 1), le nombre de permutation pour les n-1éléments restants est

(n-1)! / ((n_1-1)! * n_2! * ...) ==
n! / n / (n_1! / n_1! * n_2! * ...) == 
n/n_1 * (n! / (n_1! * n_2! * ...)`)

Donc, nous obtenons la réponse en multipliant par n/n1, la fraction réciproque des éléments qui égalent le premier, par le résultat récursif pour le reste de la liste. La liste vide donne le cas de base de 1.

xnor
la source
Pourquoi ne mettez-vous pas /l.count(l[0])à la fin? Ensuite, vous n'avez pas besoin de cette virgule flottante icky.
feersum
4

MATL , 14 13 12 octets

fpGu"@G=s:p/

Essayez-le en ligne!

Explication

L'approche est très similaire à celle de la réponse de @ Adnan .

f       % Take input implicitly. Push array of indices of nonzero entries.
        % This gives [1 2 ... n] where n is input length.
p       % Product (compute factorial)
Gu      % Push input. Array of its unique elements
"       % For each of those unique values
  @     %   Push unique value of current iteration
  G=s   %   Number of times (s) it's present (=) in the input (G)
  :p    %   Range, product (compute factorial)
  /     %   Divide
        % End for each implicitly. Display implicitly
Luis Mendo
la source
3

05AB1E , 15 14 13 octets

Code:

D©g!rÙv®yQO!/

Explication:

               # implicit input
D©             # duplicate and save a copy to register
  g!           # factorial of input length (total nr of permutations without duplicates)
    rÙv        # for each unique number in input
       ®yQO!   # factorial of number of occurances in input
            /  # divide total nr of permutations by this
               # implicit output

Utilise l' encodage CP-1252 .

Essayez-le en ligne! .

Adnan
la source
2

JavaScript (ES6), 64 61 octets

a=>a.sort().map((x,i)=>r=r*++i/(x-y?(y=x,c=1):++c),y=r=-1)|-r

Utilise la formule donnée, sauf pour calculer chaque factorielle de façon incrémentielle (ainsi, par exemple, le r=r*++icalcule efficacementn! ).

Edit: à l'origine, j'ai accepté tous les nombres finis, mais j'ai enregistré 3 octets lorsque @ user81655 a souligné que je n'avais besoin que de prendre en charge des entiers positifs (bien que j'accepte en fait des entiers non négatifs).

Neil
la source
r*=++i/(x-y?(y=x,c=1):++c),y=r=-1)|-r?
user81655
@ user81655 Ah, je n'avais pas lu la question suffisamment à fond et j'ai oublié que je pouvais compter sur des valeurs entières positives. Je n'aime pas le *=bien car cela introduit des erreurs d'arrondi.
Neil
2

Pyth, 11 octets

/.!lQ*F/V._

Suite de tests

Utilise la formule standard n! / (count1! * count2! * ...), sauf que les factorielles des décomptes sont trouvées en comptant combien de fois chaque élément apparaît dans le préfixe menant à cela, puis en multipliant tous ces nombres ensemble.

Explication:

/.!lQ*F/V._
/.!lQ*F/V._QQ    Implicit variable introduction.
                 Q = eval(input())
         ._Q     Form all prefixes of the input.
       /V   Q    Count how many times each element occurs in the prefix
                 ending with that element.
     *F          Fold on multiplication - take the product.
 .!lQ            Take the factorial of the input length
/                Divide.
isaacg
la source
1

Pyth - 14 12 octets

/F.!M+lQ/LQ{

Suite de tests .

Maltysen
la source
1

Rubis, 75 74 octets

J'aimerais un peu que le Mathmodule de Ruby ait une fonction factorielle donc je n'ai pas eu à construire la mienne.

->l{f=->x{x<2?1:x*f[x-1]};l.uniq.map{|e|f[l.count e]}.inject f[l.size],:/}
Encre de valeur
la source
1

CJam, 17 octets

q~_,\$e`0f=+:m!:/

Testez-le ici.

Explication

q~   e# Read input and evaluate.
_,   e# Duplicate and get length.
\$   e# Swap with other copy and sort it.
e`   e# Run-length encode. Since the list is sorted, this tallies the numbers.
0f=  e# Select the tally of each number.
+    e# Prepend the length of the input.
:m!  e# Compute the factorial of each number in the list.
:/   e# Fold division over it, which divides each factorial of a tally into
     e# the factorial of the length.
Martin Ender
la source
1

Gelée, 8 octets

W;ĠL€!:/

Essayez-le en ligne!

W;ĠL€!:/ example input:             [1, 3000, 2, 2, 8]
W        wrap:                      [[1, 3000, 2, 2, 8]]
  Ġ      group index by appearance: [[1], [3, 4], [5], [2]]
 ;       concatenate:               [[1, 3000, 2, 2, 8], [1], [3, 4], [5], [2]]
   L€    map by length:             [5, 1, 2, 1, 1]
     !   [map by] factorial:        [120, 1, 2, 1, 1]
      :/ reduce by division:        120÷1÷2÷1÷1 = 60
Leaky Nun
la source
1

J, 13 octets

#(%*/)&:!#/.~

Usage

   f =: #(%*/)&:!#/.~
   f 1 3000 2 2 8
60
   f 1 1 1
1
   f 2 4 3 2 3 4 4 4 4 4 1 1
83160

Explication

#(%*/)&:!#/.~  Input: A
         #/.~  Partition A by equal values and get the size of each, these are the tallies
#              Get the size of A
      &:!      Take the factorial of both the size and the tallies
   */          Reduce using multiplication the factorial of the tallies
  %            Divide the factorial of the size by that product and return
miles
la source