Elencare le combinazioni di elementi in un set


10

Dato un insieme di nelementi, la sfida è scrivere una funzione che elenca tutte le combinazioni di kelementi di questo insieme.

Esempio

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

Esempio

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

Regole (a cura)

  • L'ordine dell'output è di tua scelta.
  • L'input può essere qualsiasi tipo di dati. Ma l'output dovrebbe essere dello stesso tipo dell'input. Se l'input è un elenco di numeri interi, anche l'output deve essere un elenco di numeri interi. Se l'input è una stringa (matrice di caratteri), anche l'output dovrebbe essere una stringa.
  • Il codice dovrebbe funzionare con qualsiasi numero di variabili di input.
  • Puoi usare qualsiasi linguaggio di programmazione.
  • La risposta dovrebbe essere in grado di usare qualsiasi cosa (stringa, int, doppio ...) come input e output.
  • È vietata qualsiasi funzione integrata correlata a combinazioni e permutazioni.
  • Vince il codice più breve (in termini di byte).
  • Tiebreaker: voti.
  • Durata: 1 settimana

PS Fai attenzione agli input estremi come numeri negativi, 0, ecc.


1
Sebbene codegolf.stackexchange.com/questions/6380/… abbia una restrizione aggiuntiva, le sue risposte potrebbero essere copiate invariate e sarebbe comunque difficile da battere.
Peter Taylor,

1
Da L'ingresso può essere qualsiasi tipo di dati. intendi qualsiasi tipo di dati iterabili o iterabili riempiti con qualsiasi tipo di dati? ad es. è combos('ab', 1) -> ['a', 'b']valido?
Calvin's Hobbies,

1
Quale dovrebbe essere l'output se l'ingresso è negativo?
Ypnypn,

5
Non vedo come questa domanda sia un duplicato di "Generare combinazioni senza ricorsione" quando quasi ogni risposta finora utilizza la ricorsione.
xnor

2
La rimozione di una restrizione non è un cambiamento significativo. Inoltre, utilizzare le risposte esistenti per determinare cosa è o non è un duplicato non è una buona idea, perché non si sarebbe in grado di identificare i duplicati fino a quando non avessero già ricevuto risposta. A volte devi solo usare la testa.
Rainbolt,

Risposte:


13

Haskell - 57 46 byte

Portalo avanti, golfscripters.

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

Caso d'uso (la stessa funzione funziona polimorficamente):

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

3% "cheat" ➔ ["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"]]


1
Grazie Marco, non ho nemmeno preso in considerazione l'idea di farlo.
ChaseC

Per inciso, cosa significa "attivalo" nel tuo dialetto? Nel mio implica una sfida, ma non ha senso nel contesto perché la tua versione finale è ancora più lunga della mia versione iniziale nella domanda che questo duplica.
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 funzione faccetta un elenco Se un numero ke restituisce un elenco di tutti gli elenchi secondari di lunghezza kdi S. Piuttosto che elencare tutti i sottoinsiemi e quindi filtrare per dimensione, ottengo solo i sottoinsiemi delle dimensioni necessarie ad ogni passaggio.

Mi piacerebbe mettermi S.pop()al lavoro per combinare il S[:1]passare con il passare S[1:]dopo, ma sembra consumare troppo l'elenco.

Per evitare l'obiezione di una soluzione Python tale infrange la regola secondo cui "Il codice dovrebbe funzionare in qualsiasi numero di variabili di input" a causa dei limiti di ricorsione, noterò che l' implementazione di Stackless Python non ha limiti di ricorsione (anche se non ho effettivamente testato questo codice con esso).

Dimostrazione:

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 []

3

Mathematica 10, 70 caratteri

Solo una traduzione della risposta di Haskell.

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

Uso:

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

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


3

Carbone , 23 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

    ²                   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

2

Python - 129

s è un elenco, k è la dimensione delle combinazioni da produrre.

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)

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]

Chiama c per eseguire:

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

Ottiene tutte le permutazioni della lista e filtra quelle con lunghezza k.


2

Pyth , 28

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

Questo è (fortemente) basato sulla risposta di Haskell.

Spiegazione:

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)

Nota: mentre la versione più recente di Pyth, 1.0.9, è stata rilasciata questa sera ed è quindi non ammissibile per questa sfida, lo stesso codice funziona perfettamente in 1.0.8.



2

05AB1E , 14 13 byte

goLε¹ybRÏ}ʒgQ

Ispirato alla risposta Charcoal di @Neil , quindi assicurati di votarlo!

Provalo online o verifica alcuni altri casi di test .

Se i builtin fossero consentiti questo avrebbe potuto essere di 2 byte :

Provalo online o verifica alcuni altri casi di test .

Spiegazione:

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)

2

APL (NARS), 80 caratteri, 160 byte

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

test e come usarlo:

  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│
└~─┘

l'output sembra ok ... ma i bug sono possibili ...

In pratica restituisce il vuoto impostato come Zilde se l'input è al di fuori dell'intervallo; se alpha è 1 restituisce gli elementi tutti uno nel suo set (è giusto?);

Questo sotto sembra un paio di caratteri in meno ma 2x più lento sopra:

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

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)

(<codice sorgente>) (['Bob', 'Sally', 'Jonah'], 2)

     [[ 'Giona', 'di Sally'] [ 'Giona', 'Bob'] [ 'di Sally', 'Bob']]

Follia del metodo di matrice

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]))

1

C # (compilatore interattivo Visual C #) , 141 byte

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)

Sfortunatamente, Tio / Mono non sembra supportare la dichiarazione di tipo T generico , quindi sono costretto a perdere qualche byte con il tipo di oggetto .

//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);

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.