Énumérer les combinaisons d'éléments dans un ensemble

10

Étant donné un ensemble d' néléments, le défi consiste à écrire une fonction qui répertorie toutes les combinaisons d' kéléments de cet ensemble.

Exemple

Set: [1, 7, 4]
Input: 2
Output: [1,7], [1,4], [7,4]

Exemple

Set: ["Charlie", "Alice", "Daniel", "Bob"]
Input: 2
Output ["Daniel", "Bob"], ["Charlie", "Alice"], ["Alice", "Daniel"], ["Charlie", "Daniel"], ["Alice", "Bob"], ["Charlie",  "Bob"]

Règles (édité)

  • L'ordre de sortie est de votre choix.
  • L'entrée peut être n'importe quel type de données. Mais la sortie doit être du même type que l'entrée. Si l'entrée est une liste d'entiers, la sortie doit également être une liste d'entiers. Si l'entrée est une chaîne (tableau de caractères), la sortie doit également être une chaîne.
  • Le code doit fonctionner avec n'importe quel nombre de variables d'entrée.
  • Vous pouvez utiliser n'importe quel langage de programmation.
  • La réponse devrait également pouvoir utiliser n'importe quoi (chaîne, entier, double ...) comme entrée et sortie.
  • Toutes les fonctions intégrées liées aux combinaisons et permutations sont interdites.
  • Le code le plus court gagne (en termes d'octets).
  • Tiebreaker: votes.
  • Durée: 1 semaine.

PS Faites attention aux entrées extrêmes telles que les nombres négatifs, 0, etc.

padawan
la source
1
Bien que codegolf.stackexchange.com/questions/6380/… ait une restriction supplémentaire, ses réponses pourraient être copiées telles quelles et seraient toujours difficiles à battre.
Peter Taylor
1
Par L'entrée peut être n'importe quel type de données. voulez-vous dire tout type de données itérables ou un itérable rempli de tout type de données? par exemple est combos('ab', 1) -> ['a', 'b']valide?
Calvin's Hobbies
1
Quelle devrait être la sortie si l'entrée est négative?
Ypnypn
5
Je ne vois pas comment cette question est un doublon de "Génération de combinaisons sans récursivité" quand presque toutes les réponses utilisent jusqu'à présent la récursivité.
xnor
2
La suppression d'une restriction n'est pas un changement significatif. En outre, l'utilisation de réponses existantes pour déterminer ce qui est ou non un doublon n'est pas une bonne idée, car vous ne pourrez pas identifier les doublons tant qu'ils n'auront pas déjà été répondus. Parfois, il suffit d'utiliser sa tête.
Rainbolt

Réponses:

13

Haskell - 57 46 octets

Apportez-le, golfscripters.

0%_=[[]]
n%(x:y)=map(x:)((n-1)%y)++n%y
_%_=[]

Cas d'utilisation (la même fonction fonctionne de manière polymorphe):

2% [1,2,3,4] ➔ [[1,2], [1,3], [1,4], [2,3], [2,4], [3,4]]

3% "triche" ➔ ["che", "cha", "cht", "cea", "cet", "cat", "hea", "het", "hat", "eat"]

2% ["Charlie", "Alice", "Daniel", "Bob"] ➔ [["Charlie", "Alice"], ["Charlie", "Daniel"], ["Charlie", "Bob"] , ["Alice", "Daniel"], ["Alice", "Bob"], ["Daniel", "Bob"]]

ChaseC
la source
1
Merci Mark, je n'ai même pas envisagé de le faire infixer.
ChaseC
Soit dit en passant, que signifie «provoquer» dans votre dialecte? Dans le mien, cela implique un défi, mais cela n'a pas de sens dans le contexte car votre version finale est toujours plus longue que ma version initiale dans la question que cela reproduit.
Peter Taylor
7

Python (72)

f=lambda S,k:S and[T+S[:1]for T in f(S[1:],k-1)]+f(S[1:],k)or[[]]*(k==0)

La fonction fprend une liste Set un nombre ket renvoie une liste de toutes les sous-listes de longueur kde S. Plutôt que de répertorier tous les sous-ensembles, puis de filtrer par taille, je n'obtiens que les sous-ensembles de la taille requise à chaque étape.

Je voudrais me mettre S.pop()au travail afin de combiner arriver S[:1]avec passer S[1:]plus tard, mais cela semble consommer trop la liste.

Pour anticiper l'objection, une telle solution Python enfreint la règle selon laquelle "le code devrait fonctionner dans n'importe quel nombre de variables d'entrée" en raison des limites de récursivité, je noterai que l' implémentation Stackless Python n'a pas de limites de récursivité (bien que je n'ai pas réellement testé ce code avec lui).

Manifestation:

S = [1, 2, 6, 8]
for i in range(-1,6):print(i, f(S,i))

#Output:    
-1 []
0 [[]]
1 [[1], [2], [6], [8]]
2 [[2, 1], [6, 1], [8, 1], [6, 2], [8, 2], [8, 6]]
3 [[6, 2, 1], [8, 2, 1], [8, 6, 1], [8, 6, 2]]
4 [[8, 6, 2, 1]]
5 []
xnor
la source
3

Mathematica 10, 70 caractères

Juste une traduction de la réponse Haskell.

_~f~_={};_~f~0={{}};{x_,y___}~f~n_:=Join[Append@x/@f[{y},n-1],{y}~f~n]

Usage:

Dans [1]: = f [{1, 7, 4}, 2]

Out [1] = {{7, 1}, {4, 1}, {4, 7}}

alephalpha
la source
3

Fusain , 23 octets

EΦEX²Lθ⮌↨ι²⁼ΣιηΦ…θLι§ιμ

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

    ²                   Literal 2
   X                    Raised to power
     L                  Length of
      θ                 Input array
  E                     Mapped over implicit range
         ι              Current index
        ↨               Converted to base
          ²             Literal 2
       ⮌                Reversed
 Φ                      Filtered on
            Σ           Digital sum of
             ι          Current base 2 value
           ⁼            Equal to
              η         Input `k`
E                       Mapped to
                 θ      Input array
                …       Chopped to length
                  L     Length of
                   ι    Current base 2 value
               Φ        Filtered on
                     ι  Current base 2 value
                    §   Indexed by
                      μ Current index
Neil
la source
2

Python - 129

s est une liste, k est la taille des combinaisons à produire.

def c(s, k):
    if k < 0: return []
    if len(s) == k: return [s]
    return list(map(lambda x: [s[0]]+x, c(s[1:], k-1))) + c(s[1:], k)
CesiumLifeJacket
la source
2

Python, 102

p=lambda s:p(s[1:])+[x+[s[0]]for x in p(s[1:])]if s else[s];c=lambda s,k:[x for x in p(s)if len(x)==k]

Appelez c pour exécuter:

c ([5, 6, 7], 2) => [[6, 7], [5, 7], [5, 6]]

Il obtient toutes les permutations de la liste s et filtre celles de longueur k.

Loisirs de Calvin
la source
2

Pyth , 28

DcGHR?+m+]'HdctGtHcGtHH*]Y!G

Ceci est (fortement) basé sur la réponse Haskell.

Explication:

DcGH                           def c(G,H):
    R                          return
     ?                         Python's short circuiting _ if _ else _
       m+]'Hd                  map to [head(H)]+d
             ctGtH             c(G-1,tail(H))
       m+]'HdctGtH             map [head(H)]+d for d in c(tail(G),tail(H))
      +m+]'HdctGtHcGtH         (the above) + c(G,tail(H))
     ?                H        (the above) if H else (the below)
                       *]Y!G   [[]]*(not G)

Remarque: Bien que la version la plus récente de Pyth, 1.0.9, soit sortie ce soir, et ne soit donc pas éligible pour ce défi, le même code fonctionne correctement dans 1.0.8.

isaacg
la source
2

Haskell + Data.List , 44 octets

0%_=[[]]
n%y=do{a:b<-tails y;(a:)<$>(n-1)%b}

Essayez-le en ligne!


La réponse de 46 octets est assez difficile à battre , mais si vous avez tailsde Data.Listvous pouvez faire 44 octets.

Ad Hoc Garf Hunter
la source
2

05AB1E , 14 13 octets

goLε¹ybRÏ}ʒgQ

Inspiré par la réponse au charbon de bois de @Neil , alors assurez-vous de lui donner un vote positif!

Essayez-le en ligne ou vérifiez quelques cas de test supplémentaires .

Si les builtins étaient autorisés, cela aurait pu être de 2 octets :

Essayez-le en ligne ou vérifiez quelques cas de test supplémentaires .

Explication:

g              # Get the length of the first (implicit) input-list
 o             # Take 2 to the power this length
  L            # Create a list in the range [1, 2**length]
   ε           # Map each integer `y` to:
    ¹          #  Push the first input-list again
     ybR       #  Convert integer `y` to binary, and reverse it
        Ï      #  And only keep values at truthy indices of `y` (so where the bit is a 1)
             # After the map: filter the list of lists by:
           g   #  Where the length of the inner list
            Q  #  Is equal to the (implicit) input-integer
               # (then the result is output implicitly)

             # Get all `b`-element combinations in list `a`,
               # where `b` is the first (implicit) input-integer,
               # and `a` is the second (implicit) input-list
               # (then the result is output implicitly)
Kevin Cruijssen
la source
2

APL (NARS), 80 caractères, 160 octets

{h←{0=k←⍺-1:,¨⍵⋄(k<0)∨k≥i←≢w←⍵:⍬⋄↑,/{w[⍵],¨k h w[(⍳i)∼⍳⍵]}¨⍳i-k}⋄1≥≡⍵:⍺h⍵⋄⍺h⊂¨⍵}

test et comment l'utiliser:

  f←{h←{0=k←⍺-1:,¨⍵⋄(k<0)∨k≥i←≢w←⍵:⍬⋄↑,/{w[⍵],¨k h w[(⍳i)∼⍳⍵]}¨⍳i-k}⋄1≥≡⍵:⍺h⍵⋄⍺h⊂¨⍵}
  o←⎕fmt
  o 5 f 1 2 3 4
┌0─┐
│ 0│
└~─┘
  o 4 f 1 2 3 4 
┌1─────────┐
│┌4───────┐│
││ 1 2 3 4││
│└~───────┘2
└∊─────────┘
  o 3 f 1 2 3 4
┌4──────────────────────────────────┐
│┌3─────┐ ┌3─────┐ ┌3─────┐ ┌3─────┐│
││ 1 2 3│ │ 1 2 4│ │ 1 3 4│ │ 2 3 4││
│└~─────┘ └~─────┘ └~─────┘ └~─────┘2
└∊──────────────────────────────────┘
  o 2 f 1 2 3 4
┌6────────────────────────────────────────┐
│┌2───┐ ┌2───┐ ┌2───┐ ┌2───┐ ┌2───┐ ┌2───┐│
││ 1 2│ │ 1 3│ │ 1 4│ │ 2 3│ │ 2 4│ │ 3 4││
│└~───┘ └~───┘ └~───┘ └~───┘ └~───┘ └~───┘2
└∊────────────────────────────────────────┘
  o 1 f 1 2 3 4
┌4──────────────────┐
│┌1─┐ ┌1─┐ ┌1─┐ ┌1─┐│
││ 1│ │ 2│ │ 3│ │ 4││
│└~─┘ └~─┘ └~─┘ └~─┘2
└∊──────────────────┘
  o 0 f 1 2 3 4
┌0─┐
│ 0│
└~─┘
  o ¯1 f 1 2 3 4
┌0─┐
│ 0│
└~─┘
  o 3 f (0 0)(1 2)(3 ¯4)(4 ¯5)
┌4────────────────────────────────────────────────────────────────────────────────────────────────┐
│┌3────────────────────┐ ┌3────────────────────┐ ┌3─────────────────────┐ ┌3─────────────────────┐│
││┌2───┐ ┌2───┐ ┌2────┐│ │┌2───┐ ┌2───┐ ┌2────┐│ │┌2───┐ ┌2────┐ ┌2────┐│ │┌2───┐ ┌2────┐ ┌2────┐││
│││ 0 0│ │ 1 2│ │ 3 ¯4││ ││ 0 0│ │ 1 2│ │ 4 ¯5││ ││ 0 0│ │ 3 ¯4│ │ 4 ¯5││ ││ 1 2│ │ 3 ¯4│ │ 4 ¯5│││
││└~───┘ └~───┘ └~────┘2 │└~───┘ └~───┘ └~────┘2 │└~───┘ └~────┘ └~────┘2 │└~───┘ └~────┘ └~────┘2│
│└∊────────────────────┘ └∊────────────────────┘ └∊─────────────────────┘ └∊─────────────────────┘3
└∊────────────────────────────────────────────────────────────────────────────────────────────────┘
  o 4 f (0 0)(1 2)(3 ¯4)(4 ¯5)
┌1──────────────────────────────┐
│┌4────────────────────────────┐│
││┌2───┐ ┌2───┐ ┌2────┐ ┌2────┐││
│││ 0 0│ │ 1 2│ │ 3 ¯4│ │ 4 ¯5│││
││└~───┘ └~───┘ └~────┘ └~────┘2│
│└∊────────────────────────────┘3
└∊──────────────────────────────┘
  o 1 f (0 0)(1 2)(3 ¯4)(4 ¯5)
┌4────────────────────────────────────┐
│┌1─────┐ ┌1─────┐ ┌1──────┐ ┌1──────┐│
││┌2───┐│ │┌2───┐│ │┌2────┐│ │┌2────┐││
│││ 0 0││ ││ 1 2││ ││ 3 ¯4││ ││ 4 ¯5│││
││└~───┘2 │└~───┘2 │└~────┘2 │└~────┘2│
│└∊─────┘ └∊─────┘ └∊──────┘ └∊──────┘3
└∊────────────────────────────────────┘
  o 2 f ('Charli')('Alice')('Daniel')('Bob')
┌6──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│┌2─────────────────┐ ┌2──────────────────┐ ┌2───────────────┐ ┌2─────────────────┐ ┌2──────────────┐ ┌2───────────────┐│
││┌6──────┐ ┌5─────┐│ │┌6──────┐ ┌6──────┐│ │┌6──────┐ ┌3───┐│ │┌5─────┐ ┌6──────┐│ │┌5─────┐ ┌3───┐│ │┌6──────┐ ┌3───┐││
│││ Charli│ │ Alice││ ││ Charli│ │ Daniel││ ││ Charli│ │ Bob││ ││ Alice│ │ Daniel││ ││ Alice│ │ Bob││ ││ Daniel│ │ Bob│││
││└───────┘ └──────┘2 │└───────┘ └───────┘2 │└───────┘ └────┘2 │└──────┘ └───────┘2 │└──────┘ └────┘2 │└───────┘ └────┘2│
│└∊─────────────────┘ └∊──────────────────┘ └∊───────────────┘ └∊─────────────────┘ └∊──────────────┘ └∊───────────────┘3
└∊──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
  o ¯2 f ('Charli')('Alice')('Daniel')('Bob')
┌0─┐
│ 0│
└~─┘

la sortie semble correcte ... mais un bug est possible ...

En pratique, il renvoie un ensemble vide défini comme Zilde si l'entrée alpha est hors plage; si alpha vaut 1, il renvoie tous les éléments dans son ensemble (est-ce vrai?);

Ceci en dessous, il semble un couple de caractères de moins mais 2x plus lent au-dessus:

f←{(⍺>≢⍵)∨⍺≤0:⍬⋄1=⍺:,¨⍵⋄{w[⍵]}¨k/⍨{∧/</¨¯1↓{⍵,¨1⌽⍵}⍵}¨k←,⍳⍺⍴≢w←⍵}
RosLuP
la source
1

JS - 117 188

(a,b,c=[])=>((d=(e,f,g=[])=>f*e?g.push(e)+d(e-1,f-1,g)+g.pop
()+d(e-1,f,g):f||c.push(g.map(b=>a[b-1])))(a.length,b),c)

(<code source>) (['Bob', 'Sally', 'Jonah'], 2)

     [['Jonas', 'Sally'] ['Jonas', 'Bob'] ['Sally', 'Bob']]

La folie de la méthode des tableaux

combination = (arr, k) =>
    Array
        .apply(0, { length: Math.pow(k+1, arr.length) })
        .map(Number.call, Number)
        .map(a => a
              .toString(arr.length)
              .split('')
              .sort()
              .filter((a, b, c) => c.indexOf(a) == b)
              .join(''))
        .filter((a, b, c) => a.length == k && c.indexOf(a) == b)
        .map(x => x.split('').map(y => arr[+y]))
être
la source
1

C # (Visual C # Interactive Compiler) , 141 octets

l=>l.Any()?A(l.Skip(1)).Select(x=>l.Take(1).Union(x)).Union(A(l.Skip(1))):new object[][]{new object[]{}};B=(n,l)=>A(l).Where(x=>x.Count()==n)

Malheureusement, Tio / Mono ne semble pas prendre en charge la déclaration générique de type T , donc je suis obligé de perdre quelques octets avec le type d' objet à la place.

//returns a list of all the subsets of a list
A=l=>l.Any()?A(l.Skip(1)).Select(x=>l.Take(1).Union(x)).Union(A(l.Skip(1))):new object[][]{new object[]{}};

//return the subsets of the required size
B=(n,l)=>A(l).Where(x=>x.Count()==n);

Essayez-le en ligne!

Innat3
la source