Гольф Проблема Подмножества Суммы


15

задача

Учитывая список разделенных пробелом целых чисел в качестве входных данных, выведите все уникальные непустые подмножества этих чисел, которые каждое подмножество суммирует в 0.


Прецедент

Вход: 8 −7 5 −3 −2
Выход:-3 -2 5


Критерий победы

Это , поэтому выигрывает самый короткий код в байтах!


1
Должны ли мы беспокоиться об уникальности, если вход содержит неуникальные числа? Другими словами, сколько результатов я должен распечатать для ввода 3 3 -3 -3?
Кит Рэндалл

@Keith. По соглашению, наборы состоят из отдельных элементов, которые появляются не более одного раза. Мультисеты могут иметь элементы, которые появляются более одного раза. en.wikipedia.org/wiki/Multiset
DavidC

4
@DavidCarraher, OP смешивает терминологию, говоря о подмножествах списков.
Питер Тейлор

@PeterTaylor Спасибо. Хорошая точка зрения.
DavidC

Ответы:


4

GolfScript, 41 символ

~][[]]\{`{1$+$}+%}%;(;.&{{+}*!},{" "*}%n*

Если вам не нужен конкретный формат вывода, вы можете сократить код до 33 символов.

~][[]]\{`{1$+$}+%}%;(;.&{{+}*!},`

Пример (см. Онлайн ):

> 8 -7 5 -3 -2 4
-3 -2 5
-7 -2 4 5
-7 -3 -2 4 8


4

Питон, 119 символов

def S(C,L):
 if L:S(C,L[1:]);S(C+[L[0]],L[1:])
 elif sum(map(int,C))==0and C:print' '.join(C)
S([],raw_input().split())

Рекурсивно перечисляет все 2 ^ n подмножеств и проверяет каждое.


Браво! Я пришел в характер ...
Бут

3

Питон, 120

Я персонаж хуже, чем решение Кейта. Но ... это слишком близко, чтобы не публиковать. Одна из моих любимых особенностей code-golf - насколько могут быть разные решения одинаковой длины.

l=raw_input().split()
print[c for c in[[int(j)for t,j in enumerate(l)if 2**t&i]for i in range(1,2**len(l))]if sum(c)==0]

2

Python ( 128 137 136)

Черт возьми itertools.permutations, за такое длинное имя!

Решение грубой силы. Я удивлен, что это не самое короткое: но я думаю, itertoolsразрушает решение.

Ungolfed:

import itertools
initial_set=map(int, input().split())
ans=[]
for length in range(1, len(x)+1):
    for subset in itertools.permutations(initial_set, length):
        if sum(subset)==0:
            ans+=str(sorted(subset))
print set(ans)

Гольф (безобразный выход):

from itertools import*
x=map(int,input().split())
print set(`sorted(j)`for a in range(1,len(x)+1)for j in permutations(x,a)if sum(j)==0)

Гольф (симпатичный выход) (183):

from itertools import*
x=map(int,input().split())
print `set(`sorted(j)`[1:-1]for a in range(1,len(x)+1)for j in permutations(x,a)if sum(j)==0)`[5:-2].replace("'","\n").replace(",","")

import itertools as i: импорт модуля itertools и вызов его i

x=map(int,input().split()): разделяет ввод пробелами, а затем превращает элементы результирующих списков в целые числа ( 2 3 -5-> [2, 3, -5])

set ( sorted(j)для диапазона in (1, len (x) +1) для j в i.permutations (x, a) if sum (j) == 0):
возвращает список всех подмножеств в xотсортированном виде, где сумма 0, а затем получает только уникальные предметы
( set(...))

Могилы (`) вокруг sorted(j)- это сокращение от Python repr(sorted(j)). Причина этого заключается в том, что наборы в Python не могут обрабатывать списки, поэтому следующая лучшая вещь - это использовать строки со списком в качестве текста.


Я не понимаю, как вы получаете целые числа вместо строк. split()создает список строк, но потом вы вызываете sumподмножества этого разбиения.
Кит Рэндалл

@KeithRandall: facepalm Я спешил, поэтому я не проверял свой код. Спасибо за указание на это.
beary605 10.10.12

Вы, вероятно, можете сохранить персонажа, выполнивfrom itertools import*
Мэтт

на самом деле могилы это стенография дляrepr()
gnibbler

@gnibbler: Это будет иметь больше смысла при запуске `'привет'`. Благодарность!
beary605

2

C # - 384 символа

Хорошо, функциональное программирование на C # не так уж и мало , но мне это нравится ! (Используя просто перебор, ничего лучше.)

using System;using System.Linq;class C{static void Main(){var d=Console.ReadLine().Split(' ').Select(s=>Int32.Parse(s)).ToArray();foreach(var s in Enumerable.Range(1,(1<<d.Length)-1).Select(p=>Enumerable.Range(0,d.Length).Where(i=>(p&1<<i)!=0)).Where(p=>d.Where((x,i)=>p.Contains(i)).Sum()==0).Select(p=>String.Join(" ",p.Select(i=>d[i].ToString()).ToArray())))Console.WriteLine(s);}}

Отформатирован и прокомментирован для большей читабельности:

using System;
using System.Linq;

class C
{
    static void Main()
    {
        // read the data from stdin, split by spaces, and convert to integers, nothing fancy
        var d = Console.ReadLine().Split(' ').Select(s => Int32.Parse(s)).ToArray();
        // loop through all solutions generated by the following LINQ expression
        foreach (var s in
            // first, generate all possible subsets; well, first just their numbers
            Enumerable.Range(1, (1 << d.Length) - 1)
            // convert the numbers to the real subsets of the indices in the original data (using the number as a bit mask)
            .Select(p => Enumerable.Range(0, d.Length).Where(i => (p & 1 << i) != 0))
            // and now filter those subsets only to those which sum to zero
            .Where(p => d.Where((x, i) => p.Contains(i)).Sum() == 0)
            // we have the list of solutions here! just convert them to space-delimited strings
            .Select(p => String.Join(" ", p.Select(i => d[i].ToString()).ToArray()))
        )
            // and print them!
            Console.WriteLine(s);
    }
}

2

SWI-Пролог 84

Эта версия печатает список, вместо того, чтобы пытаться найти соответствующую привязку для термина в предикате.

s([],O):-O=[_|_],sum_list(O,0),print(O).
s([H|T],P):-s(T,[H|P]).
s([_|T],O):-s(T,O).

Метод ввода

s([8,-7,5,-3,-2,4],[]).

Для записи это версия, которая находит привязку для удовлетворения предиката:

s(L,O):-s(L,0,O),O=[_|_].
s([],0,[]).
s([H|T],S,[H|P]):-R is H+S,s(T,R,P).
s([_|T],S,O):-s(T,S,O).

Метод ввода

s([8,-7,5,-3,-2,4],O).

Предыдущая версия содержит неполное решение, которое не удалось удалить пустой набор.


2

Mathematica 62 57 38

Код

Ввод введен как целые числа в массиве x.

x

вход

Grid@Select[Subsets@x[[1, 1]], Tr@# == 0 &]

Выход

выход


объяснение

x[[1, 1]] преобразует входные данные в список целых чисел.

Subsets генерирует все подмножества из целых чисел.

Select....Tr@# == 0 дает все те подмножества, которые имеют общее значение, равное 0.

Grid форматирует выбранные подмножества как разделенные пробелом целые числа.


2

Желе , 6 байт

ŒPḊSÐḟ

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

Просто для полноты. Как и в Brachylog, Jelly также откладывает вызов, но теперь новые языки конкурируют нормально.

ŒP       Power set.
  Ḋ      Dequeue, remove the first element (empty set).
    Ðḟ   Filter out the subsets with truthy (nonzero)...
   S       sum.


1

J, 57 53 51 49 символов

>a:-.~(#:@i.@(2&^)@#<@":@(#~0=+/)@#"1 _])".1!:1[1

Использование:

   >a:-.~(#:@i.@(2&^)@#<@":@(#~0=+/)@#"1 _])".1!:1[1
8 _7 5 _3 _2 4
5 _3 _2
_7 5 _2 4
8 _7 _3 _2 4

Переписывая поезд, (<@":@(#~0=+/)@#"1 _~2#:@i.@^#)сохраняются 4 символа.
алгоритм

1

Stax , 8 байтов CP437

â±3╒yΣ╓à

Запускать и отлаживать онлайн!

объяснение

Использует распакованную версию (9 байт) для объяснения.

LS{|+!fmJ
L            Convert to list
 S           Powerset
  {   f      Filter with block
   |+!       Sum is zero
       mJ    Print each subset, joined by spaces

Given a list of space-delimited integers as input; вы - однако - берете список в качестве входных данных.
Джонатан Фрех

Исправит за счет одного байта.
Вейцзюнь Чжоу

1

J , 34 байта

(a:-.~](<@#~0=+/)@#~[:#:@i.2^#)@".

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

как

".преобразует вход в список. тогда:

a: -.~ ] (<@#~ (0 = +/))@#~ [: #:@i. 2 ^ #
                                  i.       NB. ints from 0 to...
                                     2 ^ # NB. 2 to the input len
                            [: #:@         NB. converted to binary masks
       ] (             ) #~                NB. filter the input using
                                           NB. using those masks, giving
                                           NB. us all subsets
         (             )@                  NB. and to each one...
         (  #~ (0 = +/))                   NB. return it if its sum is
                                           NB. 0, otherwise make it 
                                           NB. the empty list.
         (<@           )                   NB. and box the result.
                                           NB. now we have our answers
                                           NB. and a bunch of empty 
                                           NB. boxes, or aces (a:).
a: -.~                                     NB. remove the aces.

1

Perl 6 , 51 байт

*.words.combinations.skip.grep(!*.sum)>>.Bag.unique

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

Возвращает список уникальных сумок, сумма которых равна 0. Сумка - это взвешенный набор.

Объяснение:

*.words                 # Split by whitespace
 .combinations          # Get the powerset
 .skip                  # Skip the empty list
 .grep(!*.sum)          # Select the ones that sum to 0
 >>.Bag                 # Map each to a weighted Set
 .unique                # And get the unique sets

0

Рубин, 110 байт

a=gets.split.map &:to_i;b=[];(1...a.length).each{|c|a.permutation(c){|d|d.sum==0?b<<d:0}};p b.map(&:sort).uniq

Добавлю ссылку TIO позже.

Принимает ввод из стандартного ввода в виде списка чисел, например 8 −7 5 −3 −2

Как это работает: преобразует входные данные в массив чисел. Получает все перестановки длин от 1 до длины массива. Он добавляет их в выходной массив, если их сумма равна 0. Он выводит массив без дубликатов.

Выход для образца ввода: [[-3, -2, 5]]

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.