Розмістіть проблему підмножини


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

Я характер гірший за рішення Кіта. Але ... це занадто близько, щоб не публікувати. Однією з моїх улюблених особливостей коду-гольфу є те, наскільки різними можуть бути рішення подібної довжини.

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

Пітон ( 128 137 136)

Чорт за тобою, itertools.permutationsза те, що маєш таке довге ім’я!

Рішення грубої сили. Я здивований, що це не найкоротше: але, мабуть, itertoolsруйнує рішення.

Безголівки:

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)для діапазону (1, len (x) +1) для j в i.permutations (x, a) якщо sum (j) == 0):
Повертає список усіх підмножин у x, відсортований, де сума дорівнює 0, а потім отримує лише унікальні елементи
(set(...) )

Могили (`) навколо sorted(j)є скороченням Python для repr(sorted(j)). Причина цього тут полягає в тому, що набори в Python не можуть обробляти списки, тому наступне найкраще - використовувати рядки зі списком як текст.


Мене бентежить питання про те, як ви отримуєте цілі числа замість рядків. split()складає список рядків, але пізніше ви викликаєте sumпідмножини розбиття.
Кіт Рендалл

@KeithRandall: facepalm я поспішав, тому не перевіряв свій код. Дякую, що вказали на це.
beary605

Можливо, ви можете зберегти персонажа, зробивши цеfrom itertools import*
Метт

насправді могили є стенограмоюrepr()
гніблер

@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-Prolog 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

Математика 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Ðḟ

Спробуйте в Інтернеті!

Просто для повноти. Як і Брахілог, 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.

Приймає введення зі stdin як список номерів, наприклад 8 −7 5 −3 −2

Як це працює: Він перетворює вхід у масив чисел. Отримує всі перестановки довжин від 1 до довжини масиву. Він додає їх до вихідного масиву, якщо вони дорівнюють 0. Він виводить масив без дублікатів.

Вихідні дані для вибірки: [[-3, -2, 5]]

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.