Перечислите комбинации элементов в наборе

10

Учитывая набор nэлементов, задача состоит в том, чтобы написать функцию, которая перечисляет все комбинации kэлементов в этом наборе.

пример

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

пример

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

Правила (отредактировано)

  • Порядок вывода на ваш выбор.
  • На входе могут быть данные любого типа. Но вывод должен быть того же типа, что и ввод. Если входные данные представляют собой список целых чисел, выходные данные также должны быть списком целых чисел. Если вход является строкой (массив символов), вывод также должен быть строкой.
  • Код должен работать с любым количеством входных переменных.
  • Вы можете использовать любой язык программирования.
  • Ответ должен иметь возможность использовать что угодно (string, int, double ...) в качестве входных и выходных данных.
  • Любые встроенные функции, связанные с комбинациями и перестановками, запрещены.
  • Самый короткий код выигрывает (в байтах).
  • Tiebreaker: голоса
  • Продолжительность: 1 неделя.

PS Будьте осторожны с экстремальными значениями, такими как отрицательные числа, 0 и т. Д.

падаван
источник
1
Хотя у codegolf.stackexchange.com/questions/6380/… есть дополнительное ограничение, его ответы могут быть скопированы без изменений, и их все равно будет сложно обойти.
Питер Тейлор
1
По данным ввода могут быть любые типы данных. Вы имеете в виду любой тип итерируемых данных или итеративный, заполненный любым типом данных? например combos('ab', 1) -> ['a', 'b']действителен?
Увлечения Кэлвина
1
Каким должен быть выход, если вход отрицательный?
Ypnypn
5
Я не вижу, как этот вопрос является дубликатом «Создание комбинаций без рекурсии», когда почти каждый ответ до сих пор использует рекурсию.
xnor
2
Снятие ограничения не является значительным изменением. Кроме того, использование существующих ответов для определения того, что является или не является дубликатом, не является хорошей идеей, поскольку вы не сможете идентифицировать дубликаты до тех пор, пока на них уже не будет ответа. Иногда вам просто нужно использовать свою голову.
Рейнболт

Ответы:

13

Haskell - 57 46 байт

Принеси это, гольфисты.

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

Вариант использования (та же функция работает полиморфно):

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% ["Чарли", "Алиса", "Даниэль", "Боб"] ➔ [["Чарли", "Алиса"], ["Чарли", "Даниэль"], ["Чарли", "Боб"] [ "Алиса", "Даниил"], [ "Алиса", "Боб"], [ "Даниил", "Боб"]]

ChaseC
источник
1
Спасибо Марк, я даже не подумал сделать это инфиксом.
ChaseC
Между прочим, что означает "вызвать это" на вашем диалекте? По моему это вызов, но это не имеет смысла в контексте, потому что ваша окончательная версия все еще длиннее, чем моя первоначальная версия в вопросе, который дублирует.
Питер Тейлор
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)

Функция fпринимает список Sи число kи возвращает список всех подсписков длины kв S. Вместо того, чтобы перечислять все подмножества и затем фильтровать по размеру, я получаю только подмножества нужного размера на каждом шаге.

Я хотел бы приступить S.pop()к работе, чтобы объединить получение S[:1]с передачей S[1:]позже, но кажется, что он слишком много потребляет.

Чтобы исключить возражение, любое такое решение Python нарушает правило «код должен работать с любым количеством входных переменных» из-за пределов рекурсии, я отмечу, что реализация Stackless Python не имеет пределов рекурсии (хотя я на самом деле не тестировал этот код с ним).

Демонстрация:

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
источник
3

Mathematica 10, 70 символов

Просто перевод ответа на Haskell.

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

Применение:

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

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

alephalpha
источник
3

Древесный уголь , 23 байта

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

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

    ²                   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

Питон - 129

s - это список, k - размер создаваемых комбинаций.

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
источник
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]

Звоните с, чтобы запустить:

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

Он получает все перестановки в списке s и фильтрует те, которые имеют длину k.

Кальвин Хобби
источник
2

Пиф , 28

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

Это (в значительной степени) основано на ответе на Haskell.

Объяснение:

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)

Примечание. Хотя самая последняя версия Pyth, 1.0.9, была выпущена сегодня вечером и поэтому не подходит для этой задачи, тот же код отлично работает в 1.0.8.

isaacg
источник
2

Haskell + Data.List , 44 байта

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

Попробуйте онлайн!


46 байт Ответ довольно трудно превзойти , но если у вас есть tailsот Data.Listвы можете сделать 44 байта.

Специальный охотник за гарфами
источник
2

05AB1E , 14 13 байт

goLε¹ybRÏ}ʒgQ

Вдохновленный ответом @Neil 's Charcoal , так что не забудьте его поддержать!

Попробуйте онлайн или проверьте еще несколько тестов .

Если встроенные функции были разрешены, это могло бы быть 2 байта :

Попробуйте онлайн или проверьте еще несколько тестов .

Объяснение:

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 символов, 160 байтов

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

тест и как его использовать:

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

вывод вроде ок ... но ошибка возможна ...

На практике он возвращает void, установленный как Zilde, если входная альфа выходит за пределы диапазона; если альфа равен 1, он возвращает все элементы в своем наборе (верно?);

Это ниже, кажется, на пару символов меньше, но выше в 2 раза:

f←{(⍺>≢⍵)∨⍺≤0:⍬⋄1=⍺:,¨⍵⋄{w[⍵]}¨k/⍨{∧/</¨¯1↓{⍵,¨1⌽⍵}⍵}¨k←,⍳⍺⍴≢w←⍵}
RosLuP
источник
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)

(<исходный код>) (['Боб', 'Салли', 'Иона'], 2)

     [[ 'Ионы', 'Салли'] [ 'Ионы', 'Bob'] [ 'Sally', 'Bob']]

Метод массива безумия

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 # (интерактивный компилятор Visual C #) , 141 байт

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)

К сожалению, Tio / Mono, похоже, не поддерживает объявление универсального типа T , поэтому я вынужден вместо этого потерять несколько байтов с типом объекта .

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

Попробуйте онлайн!

Innat3
источник