Golf vấn đề tổng hợp con


15

Bài tập

Đưa ra một danh sách các số nguyên được phân tách bằng dấu cách làm đầu vào, xuất ra tất cả các tập hợp con không trống duy nhất của các số này mà mỗi tập hợp con tổng bằng 0.


Trường hợp thử nghiệm

Đầu vào: 8 −7 5 −3 −2
Đầu ra:-3 -2 5


Tiêu chí chiến thắng

Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng!


1
Chúng ta có phải lo lắng về tính duy nhất nếu đầu vào chứa các số không duy nhất không? Nói cách khác, tôi phải in bao nhiêu kết quả cho đầu vào 3 3 -3 -3?
Keith Randall

@Keith. Theo quy ước, các bộ bao gồm các yếu tố riêng biệt xuất hiện nhiều nhất một lần. Nhiều người có thể có các yếu tố xuất hiện nhiều lần. vi.wikipedia.org/wiki/Multiset
DavidC

4
@DavidCarraher, OP trộn thuật ngữ bằng cách nói về tập hợp con của danh sách.
Peter Taylor

@PeterTaylor Cảm ơn. Điểm tốt.
DavidC

Câu trả lời:


4

GolfScript, 41 ký tự

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

Nếu bạn không quan tâm đến định dạng đầu ra cụ thể, bạn có thể rút ngắn mã thành 33 ký tự.

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

Ví dụ (xem trực tuyến ):

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


4

Python, 119 ký tự

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

Liệt kê tất cả 2 ^ n tập con đệ quy và kiểm tra từng cái.


Bravo! Tôi đến trong một nhân vật ...
boothby

3

Con trăn, 120

Tôi là một nhân vật tồi tệ hơn giải pháp của Keith. Nhưng ... cái này quá gần để không đăng. Một trong những tính năng yêu thích của tôi về môn đánh gôn là cách các giải pháp có độ dài tương tự nhau có thể giống nhau.

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

Con trăn ( 128 137 136)

Mẹ kiếp itertools.permutations , vì đã có một cái tên dài như vậy!

Giải pháp vũ lực. Tôi ngạc nhiên nó không phải là ngắn nhất: nhưng tôi đoánitertools hỏng giải pháp.

Ung dung:

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)

Golfed (đầu ra xấu xí):

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)

Golfed (đầu ra khá) (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: nhập mô-đun itertools và gọi nó i

x=map(int,input().split()): tách biệt đầu vào theo khoảng trắng, sau đó biến các mục của danh sách kết quả thành số nguyên ( 2 3 -5-> [2, 3, -5])

set ( sorted(j)cho a trong phạm vi (1, len (x) +1) cho j trong i.permutations (x, a) if sum (j) == 0):
Trả về danh sách tất cả các tập hợp con trong x, được sắp xếp, trong đó tổng là 0 và sau đó chỉ nhận được các mục duy nhất
( set(...))

Các ngôi mộ (`) xung quanh sorted(j)là tốc ký Python repr(sorted(j)). Lý do tại sao điều này là ở đây vì các bộ trong Python không thể xử lý danh sách, vì vậy điều tốt nhất tiếp theo là sử dụng các chuỗi có danh sách làm văn bản.


Tôi bối rối về cách bạn nhận được số nguyên thay vì chuỗi. split()tạo một danh sách các chuỗi, nhưng sau đó bạn đang gọi sumcác tập hợp con của phân tách đó.
Keith Randall

@KeithRandall: facepalm Tôi đã vội vàng, vì vậy tôi đã không kiểm tra mã của mình. Cảm ơn bạn đã chỉ ra rằng.
beary605

Bạn có thể có thể cứu một nhân vật bằng cách thực hiệnfrom itertools import*
Matt

thực ra các ngôi mộ là viết tắt củarepr()
gnibbler

@gnibbler: Điều đó sẽ có ý nghĩa hơn rất nhiều khi chạy `'hello'`. Cảm ơn!
beary605

2

C # - 384 ký tự

OK, lập trình kiểu chức năng trong C # không phải là ngắn , nhưng tôi thích nó! (Chỉ sử dụng một phép liệt kê vũ phu, không có gì tốt hơn.)

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

Được định dạng và nhận xét để dễ đọc hơn:

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

Phiên bản này in danh sách, thay vì cố gắng tìm một ràng buộc thích hợp cho một thuật ngữ trong một vị ngữ.

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

Phương pháp nhập

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

Đối với bản ghi, đây là phiên bản tìm thấy một ràng buộc để đáp ứng vị từ:

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

Phương pháp nhập

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

Bản sửa đổi trước đó chứa một giải pháp chưa hoàn chỉnh mà không quản lý để xóa tập hợp trống.


2

Toán học 62 57 38

Đầu vào được nhập dưới dạng số nguyên trong một mảng , x.

x

đầu vào

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

Đầu ra

đầu ra


Giải trình

x[[1, 1]] chuyển đổi đầu vào thành một danh sách các số nguyên.

Subsets tạo ra tất cả các tập con từ các số nguyên.

Select....Tr@# == 0 đưa ra tất cả các tập con có tổng bằng 0.

Grid định dạng các tập con được chọn là số nguyên cách nhau bằng dấu cách.


2

Thạch , 6 byte

ŒPḊSÐḟ

Hãy thử trực tuyến!

Chỉ cần cho đầy đủ. Tương tự như Brachylog, Jelly cũng hoãn thử thách, nhưng đến nay, các ngôn ngữ mới hơn cạnh tranh bình thường.

Œ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 ký tự

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

Sử dụng:

   >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

Viết lại tàu như (<@":@(#~0=+/)@#"1 _~2#:@i.@^#)tiết kiệm 4 ký tự.
thuật toán bắt đầu

1

Stax , 8 byte CP437

â±3╒yΣ╓à

Chạy và gỡ lỗi trực tuyến!

Giải trình

Sử dụng phiên bản đã giải nén (9 byte) để giải thích.

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; bạn đang - tuy nhiên - lấy một danh sách làm đầu vào.
Jonathan Frech

Sẽ sửa chữa với chi phí của một byte.
Weijun Zhou

1

J , 34 byte

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

Hãy thử trực tuyến!

làm sao

".chuyển đổi đầu vào thành một danh sách. sau đó:

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 byte

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

Hãy thử trực tuyến!

Trả về danh sách các Túi duy nhất có tổng bằng 0. Một Túi là Tập hợp có trọng số.

Giải trình:

*.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

Ruby, 110 byte

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

Sẽ thêm liên kết TIO sau.

Lấy đầu vào từ stdin làm danh sách các số, vd 8 −7 5 −3 −2

Cách thức hoạt động: Nó chuyển đổi đầu vào thành một dãy số. Nhận tất cả các hoán vị của độ dài từ 1 đến chiều dài của mảng. Nó thêm chúng vào mảng đầu ra nếu chúng tổng bằng 0. Nó xuất ra mảng mà không trùng lặp.

Đầu ra cho đầu vào mẫu: [[-3, -2, 5]]

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.