Générer des combinaisons avec remplacement

10

Énumérez toutes les combinaisons avec remplacement (ou combinaisons avec répétition) de taille k à partir d'un ensemble de n éléments.

Une combinaison avec remplacement est un multiset non ordonné dont chaque élément est également dans l'ensemble de n éléments. Notez que:

  • Ce n'est pas ordonné. Par conséquent, un ensemble précédemment imprimé avec un ordre différent ne doit plus être imprimé.
  • Il s'agit d'un multiset. Le même élément peut (mais n'est pas requis) apparaître plusieurs fois. C'est la seule différence entre une combinaison avec remplacement et une combinaison normale.
  • L'ensemble doit avoir exactement k éléments.

Alternativement, c'est également un sous-ensemble taille- k du multiset qui contient chacun des n éléments k fois.

L'entrée doit être soit n et k , où les éléments sont les n premiers entiers positifs ou non négatifs, soit les n éléments et k , où vous pouvez supposer que les n éléments sont tous différents les uns des autres.

La sortie doit être une liste de toutes les combinaisons avec remplacement de taille k de l'ensemble donné. Vous pouvez les imprimer et les éléments dans chacun d'eux dans n'importe quel ordre.

Vous ne pouvez pas utiliser de combinaisons génératrices intégrées avec remplacement. Mais vous pouvez utiliser des fonctions intégrées pour générer des combinaisons, permutations, tuples normaux, etc.

C'est le code-golf, le code le plus court gagne.

Exemple

Input: 4 2
Output: [0 0] [0 1] [0 2] [0 3] [1 1] [1 2] [1 3] [2 2] [2 3] [3 3]
jimmy23013
la source

Réponses:

8

Gelée, 4 octets

Merci à Sp3000 pour avoir économisé 2 octets.

ṗṢ€Q

L'entrée est net kcomme arguments de ligne de commande dans cet ordre. Utilise des éléments 1pour n.

Essayez-le en ligne!

Explication

ṗ     # Get k-th Cartesion power of n.
 Ṣ€   # Sort each tuple.
   Q  # Remove duplicates.
Martin Ender
la source
8

CJam (8 octets)

{m*:$_&}

Démo en ligne

Dissection

{    e# Declare block (anonymous function); parameters are n k
  m* e# Cartesian product, which implicitly lifts n to [0 1 ... n-1]
  :$ e# Sort each element of the Cartesian product, to give them canonical forms
  _& e# Deduplicate
}
Peter Taylor
la source
3

Mathematica, 31 29 octets

Merci à A Simmons pour avoir économisé 2 octets.

{}⋃Sort/@Range@#~Tuples~#2&

Une fonction sans nom prenant net kcomme arguments entiers dans cet ordre et renvoyant une liste de listes. Les éléments seront 1à n. Fonctionne de la même manière que la réponse CJam de Peter.

Martin Ender
la source
@ jimmy23013 Pas un que je sache.
Martin Ender
Je pense que vous pouvez économiser deux octets avec{}∪Sort/@Range@#~Tuples~#2&
A Simmons
@ASimmons Belle idée, merci!
Martin Ender
3

MATL , 11 octets

(Il existe une solution à 9 octets basée sur la puissance cartésienne, mais Peter Taylor l'a déjà fait . Essayons quelque chose de différent).

Les combinaisons avec remplacement peuvent être réduites à des combinaisons sans remplacement comme suit. Nous voulons n Cr k, par exemple avec n=3, k=2:

0 0
0 1
0 2
1 1
1 2
2 2

Nous pouvons calculer n+k-1 C k:

0 1
0 2
0 3
1 2
1 3
2 3

puis soustrayez 0 1 ... k-1de chaque ligne:

+q:2GXn2G:-

Explication:

+q     % take two inputs n, k and compute n+k-1
:      % range [1,2...,n+k-1]
2G     % push second input, k
Xn     % combinations without replacement
2G:    % range [1,2,...,k]
-      % subtract with broadcast. Display

Le code fonctionne dans la version 13.1.0 du langage / compilateur, qui est antérieure au défi.

Vous pouvez l' essayer en ligne! Notez que le compilateur en ligne a été mis à jour vers la version 14.0.0 et Xndoit donc être remplacé par XN.

Luis Mendo
la source
3

JavaScript (Firefox 30-57), 71 octets

f=(n,k)=>k?[for(m of Array(n).keys())for(a of f(m+1,k-1))[...a,m]]:[[]]

Je peux utiliser keys()pour une fois.

Neil
la source
2

Rubis, 56 55 octets

Deux solutions, étonnamment toutes deux de même longueur:

->n,k{[*1..n].repeated_permutation(k).map(&:sort).uniq}
->n,k{(a=[*1..n]).product(*[a]*(k-1)).map(&:sort).uniq}

Hé, vous avez dit que nous pourrions utiliser builtins de permutation ...

Cela génère simplement toutes les permutations répétées (la seconde génère des produits cartésiens répétés) et supprime ceux qui ne sont pas triés.

Merci à Martin d'avoir sauvé un octet avec 0...n-> 1..n!

Poignée de porte
la source
1

Pyth, 7 octets

{SM^UQE

Utilise le même algorithme que la réponse de Peter.

    UQ   range(input())
      E  input()
   ^     repeated Cartesian product of ^^, ^ times
 SM      map(sort)
{        uniq
Poignée de porte
la source
1

Python, 63 octets

f=lambda n,k:n*k and[l+[n]for l in f(n,k-1)]+f(n-1,k)or[[]][k:]

Une méthode récursive. Pour faire un multiset d' kéléments, 1pour n, nous choisissons soit:

  • Inclure une autre instance de n, et il reste à faire un multi-ensemble d' k-1éléments de 1àn
  • N'incluez pas une autre instance de n, et il reste à faire un multi-ensemble d' kéléments de à 1àn-1

Nous terminons lorsque l'un kou l' autre natteint 0et s'il katteint 0, nous donnons un cas de base de la liste vide. Sinon, nous avons le mauvais nombre d'éléments, et donnons donc la liste vide.

xnor
la source
1

Python 3, 81 80

Solution récursive:

t=lambda n,k,b=0:[[]]if k<=0 else [[i]+l for i in range(b,n)for l in t(n,k-1,i)]

La fonction t(n, k, b)renvoie la liste de tous kles sous-ensembles multi-éléments de la plage de bà n. Cette liste est vide si k <= 0. Sinon, nous décomposons le problème en nous basant sur le plus petit élément du multi-sous-ensemble, que nous désignons par i.

Pour chacun idans la plage de bà n, nous générons tous les k-multi-sous-ensembles avec le plus petit élément ien commençant par [i]puis en ajoutant chaque (k-1)-multi-sous-ensemble de la plage de ià n, que nous obtenons en appelant récursivement t(n, k-1, i).

Andrew Gainer-Dewar
la source
Bienvenue sur Programmation Puzzles & Code Golf! Ceci est une belle première réponse. Pourriez-vous expliquer le fonctionnement du code?
Alex A.
Ça a l'air super. Bonne solution!
Alex A.
1

Dyalog APL , 22 octets

{∪{⍵[⍋⍵]}¨↓⍉⍺⊥⍣¯1⍳⍺*⍵}

Requiert ⎕IO←0, qui est par défaut dans de nombreux systèmes APL. Prend k comme argument de gauche, n comme argument de droite.

⍳⍺*⍵0 1 2 ... kⁿ
⍺⊥⍣¯1convertir en base k
transposer
faire la matrice en liste de listes
{⍵[⍋⍵]}¨trier chacune ...
l'unique

Adam
la source
1

J, 18 octets

[:~.#~<@/:~@#:i.@^

Approche similaire utilisée dans la solution de @ Adám .

Une autre approche utilisant un produit cartésien {pour 24 octets. Prend kle LHS et nle RHS.

~.@:(/:~&.>)@,@{@(#<@i.)

Usage

   f =: [:~.#~<@/:~@#:i.@^
   4 f 2
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│0 0│0 1│0 2│0 3│1 1│1 2│1 3│2 2│2 3│3 3│
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘

Explication

[:~.#~<@/:~@#:i.@^ Input: n on LHS and k on RHS
                 ^ Compute n^k
              i.@  Create a range [0, 1, ... n^k-1]
    #~             Create k copies on n
            #:     On each value in the range above, convert each digit to base-n
                   and take the last k digits of it
        /:~@       For each array of digits, sort it in ascending order
      <@           Box each array of digits
[:~.               Take the distinct values in the array of boxes and return it
miles
la source
1

Clojure, 94 octets

(defn f[k n](if(= 1 k)(for[i(range n)][i])(sort(set(for[i(f(dec k)n)j(range n)](conj i j))))))

Notez l'ordre des paramètres modifié: 1er est ket 2e est n. Cela a permis d'économiser 1 octet (f(dec k)n).

NikoNyrh
la source
0

Mathematica, 36 octets

{##}&~Array~Table@##~Flatten~(#2-1)&

S'il vous plaît, dites-moi qu'il y a un bonus de 1/6 pour l'utilisation de no [] s ... Ou peut-être pour les nombreuses utilisations de ##?

CalculatorFeline
la source