Wymień kombinacje elementów w zestawie

10

Biorąc pod uwagę zestaw nelementów, wyzwaniem jest napisanie funkcji, która wymienia wszystkie kombinacje kelementów w tym zestawie.

Przykład

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

Przykład

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

Reguły (edytowane)

  • Kolejność danych wyjściowych jest do wyboru.
  • Dane wejściowe mogą być dowolnego rodzaju danych. Ale dane wyjściowe powinny być tego samego typu co dane wejściowe. Jeśli wejściem jest lista liczb całkowitych, wyjściem powinna być również lista liczb całkowitych. Jeśli dane wejściowe to ciąg znaków (tablica znaków), dane wyjściowe również powinny być ciągiem znaków.
  • Kod powinien działać z dowolną liczbą zmiennych wejściowych.
  • Możesz użyć dowolnego języka programowania.
  • Odpowiedź powinna umożliwiać użycie dowolnego elementu (string, int, double ...) jako wejścia i wyjścia.
  • Wszelkie wbudowane funkcje związane z kombinacjami i permutacjami są zabronione.
  • Najkrótszy kod wygrywa (pod względem bajtów).
  • Tiebreaker: głosy.
  • Czas trwania: 1 tydzień.

PS Uważaj na ekstremalne dane wejściowe, takie jak liczby ujemne, 0 itd.

padawan
źródło
1
Mimo że codegolf.stackexchange.com/questions/6380/… ma dodatkowe ograniczenie, jego odpowiedzi można skopiować bez zmian i nadal byłoby trudno je pokonać.
Peter Taylor
1
Przez Dane wejściowe mogą być dowolnego rodzaju danych. masz na myśli dowolny typ danych iterowalnych lub iteracyjny wypełniony dowolnym rodzajem danych? np. czy jest combos('ab', 1) -> ['a', 'b']ważny?
Calvin's Hobbies
1
Jakie powinno być wyjście, jeśli wejście jest ujemne?
Ypnypn
5
Nie rozumiem, w jaki sposób to pytanie jest duplikatem „Generowania kombinacji bez rekurencji”, skoro prawie każda jak dotąd odpowiedź używa rekurencji.
xnor
2
Usunięcie ograniczenia nie jest znaczącą zmianą. Ponadto używanie istniejących odpowiedzi w celu ustalenia, co jest duplikatem, czy nie, nie jest dobrym pomysłem, ponieważ nie można zidentyfikować duplikatów, dopóki nie zostaną już udzielone odpowiedzi. Czasami musisz po prostu użyć głowy.
Rainbolt

Odpowiedzi:

13

Haskell - 57 46 bajtów

Dajcie spokój, golfiści.

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

Przypadek użycia (ta sama funkcja działa polimorficznie):

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

ChaseC
źródło
1
Dzięki Mark, nawet nie zastanawiałem się nad zrobieniem tego.
ChaseC
Nawiasem mówiąc, co oznacza „włącz” w twoim dialekcie? W moim przypadku oznacza to wyzwanie, ale nie ma to sensu w kontekście, ponieważ twoja ostateczna wersja jest wciąż dłuższa niż moja początkowa wersja w pytaniu, które się powiela.
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)

Funkcja fpobiera listę Si liczbę ki zwraca listę wszystkich podlist długości kdnia S. Zamiast wyświetlać wszystkie podzestawy, a następnie filtrować według rozmiaru, na każdym etapie otrzymuję tylko podzbiory wymaganego rozmiaru.

Chciałbym zabrać się S.pop()do pracy, aby później połączyć się S[:1]z zaliczeniem S[1:], ale wydaje się, że ta lista pochłania zbyt wiele.

Aby zapobiec sprzeciwowi, każde takie rozwiązanie Pythona łamie zasadę, że „Kod powinien działać w dowolnej liczbie zmiennych wejściowych” z powodu ograniczeń rekurencji, zauważę, że implementacja Pythona bez stosu nie ma limitów rekurencji (chociaż tak naprawdę nie testowałem ten kod).

Demonstracja:

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
źródło
3

Mathematica 10, 70 znaków

Tylko tłumaczenie odpowiedzi Haskella.

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

Stosowanie:

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

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

alephalpha
źródło
3

Węgiel , 23 bajty

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

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:

    ²                   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
źródło
2

Python - 129

s jest listą, k jest rozmiarem kombinacji do wytworzenia.

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
źródło
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]

Zadzwoń do c, aby uruchomić:

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

Pobiera wszystkie permutacje z listy i filtruje te o długości k.

Hobby Calvina
źródło
2

Pyth , 28

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

Jest to (w dużej mierze) oparte na odpowiedzi Haskella.

Wyjaśnienie:

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)

Uwaga: Chociaż najnowsza wersja Pyth 1.0.9 została wydana dziś wieczorem i dlatego nie kwalifikuje się do tego wyzwania, ten sam kod działa poprawnie w wersji 1.0.8.

isaacg
źródło
2

Haskell + Data.List , 44 bajty

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

Wypróbuj online!


W 46 bajt Odpowiedź jest dość trudny do pobicia, ale jeśli masz tailsze Data.Listmożna zrobić 44 bajtów.

Ad Hoc Garf Hunter
źródło
2

05AB1E , 14 13 bajtów

goLε¹ybRÏ}ʒgQ

Zainspirowany odpowiedzią na węgiel drzewny @Neil , więc upewnij się, że go głosujesz!

Wypróbuj online lub sprawdź kilka innych przypadków testowych .

Gdyby wbudowane były dozwolone, mogłyby to być 2 bajty :

Wypróbuj online lub sprawdź kilka innych przypadków testowych .

Wyjaśnienie:

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
źródło
2

APL (NARS), 80 znaków, 160 bajtów

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

test i jak go używać:

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

wynik wydaje się ok ... ale błąd jest możliwy ...

W praktyce zwraca wartość void ustawioną jako Zilde, jeśli wprowadzona alfa jest poza zakresem; jeśli alfa ma wartość 1, zwraca wszystkie elementy ze swojego zbioru (czy ma rację?);

To poniżej wydaje się kilka char mniej, ale 2x wolniej powyżej:

f←{(⍺>≢⍵)∨⍺≤0:⍬⋄1=⍺:,¨⍵⋄{w[⍵]}¨k/⍨{∧/</¨¯1↓{⍵,¨1⌽⍵}⍵}¨k←,⍳⍺⍴≢w←⍵}
RosLuP
źródło
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)

(<kod źródłowy>) ([„Bob”, „Sally”, „Jonah”], 2)

     [[„Jonah”, „Sally”] [„Jonah”, „Bob”] [„Sally”, „Bob”]]

Szaleństwo metody tablicowej

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]))
bebe
źródło
1

C # (interaktywny kompilator Visual C #) , 141 bajtów

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)

Niestety, Tio / Mono nie wydaje się obsługiwać ogólnej deklaracji typu T , więc zamiast tego jestem zmuszony stracić kilka bajtów z typem obiektu .

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

Wypróbuj online!

Innat3
źródło