Golf Masalah Subset-Jumlah


15

Tugas

Diberikan daftar bilangan bulat batas-ruang sebagai input, output semua himpunan bagian non-kosong unik dari angka-angka ini yang masing-masing subset berjumlah 0.


Kasus cobaan

Input: 8 −7 5 −3 −2
Keluaran:-3 -2 5


Kriteria Kemenangan

Ini adalah , jadi kode terpendek dalam byte menang!


1
Apakah kita harus khawatir tentang keunikan jika inputnya berisi angka-angka yang tidak unik? Dengan kata lain, berapa banyak hasil yang harus saya cetak untuk input 3 3 -3 -3?
Keith Randall

@Keith. Secara konvensional, set terdiri dari elemen berbeda yang muncul paling banyak satu kali. Multisets dapat memiliki elemen yang muncul lebih dari satu kali. en.wikipedia.org/wiki/Multiset
DavidC

4
@ Davidvidarr, OP mencampur terminologi dengan berbicara tentang himpunan bagian dari daftar.
Peter Taylor

@PeterTaylor Terima kasih. Poin yang bagus.
DavidC

Jawaban:


4

GolfScript, 41 karakter

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

Jika Anda tidak peduli dengan format output spesifik Anda dapat mempersingkat kode menjadi 33 karakter.

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

Contoh (lihat online ):

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

6

Brachylog (2), 9 karakter

{⊇.+0∧}ᵘb

Cobalah online!

{⊇.+0∧}ᵘb
 ⊇           subset
   +0        that sums to 0
  .  ∧       output the subset
{     }ᵘ     take all unique solutions
        b    except the first (which is the empty solution)

4

Python, 119 karakter

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

Menghitung semua himpunan bagian secara rekursif dan memeriksa masing-masing.


Bravo! Saya datang dalam karakter ...
Stanby

3

Python, 120

Saya seorang karakter yang lebih buruk daripada solusi Keith. Tapi ... ini terlalu dekat untuk tidak diposkan. Salah satu fitur favorit saya dari kode-golf adalah bagaimana solusi yang sama panjangnya bisa berbeda.

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)

Kurang ajar kau, itertools.permutations karena memiliki nama yang begitu panjang!

Solusi brute force. Saya terkejut itu bukan yang terpendek: tapi saya kiraitertools reruntuhan solusinya.

Tidak Disatukan:

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)

Golf (output jelek):

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)

Golf (keluaran cantik) (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: mengimpor modul itertools dan memanggilnya i

x=map(int,input().split()): memisahkan input dengan spasi, lalu mengubah item daftar yang dihasilkan menjadi bilangan bulat ( 2 3 -5-> [2, 3, -5])

set ( sorted(j)for a in range (1, len (x) +1) untuk j di i.permutations (x, a) jika jumlah (j) == 0):
Mengembalikan daftar semua himpunan bagian dalam x, disortir, di mana jumlahnya adalah 0, dan kemudian hanya mendapatkan item unik
( set(...))

Kuburan (`) di sekitar sorted(j)adalah singkatan Python repr(sorted(j)). Alasan mengapa ini ada di sini adalah karena set di Python tidak dapat menangani daftar, jadi hal terbaik berikutnya adalah menggunakan string dengan daftar sebagai teks.


Saya bingung tentang bagaimana Anda mendapatkan bilangan bulat, bukan string. split()membuat daftar string, tetapi kemudian Anda memanggil sumsubset dari pemisahan itu.
Keith Randall

@KeithRandall: facepalm saya terburu-buru, jadi saya tidak menguji kode saya. Terima kasih telah menunjukkannya.
beary605

Anda mungkin dapat menyimpan karakter dengan melakukanfrom itertools import*
Matt

sebenarnya kuburan adalah singkatan untukrepr()
gnibbler

@gnibbler: Itu akan lebih masuk akal saat menjalankan `'hello'`. Terima kasih!
beary605

2

C # - 384 karakter

OK, pemrograman bergaya fungsional dalam C # tidak sesingkat itu , tapi saya menyukainya ! (Hanya menggunakan enumerasi kasar, tidak ada yang lebih baik.)

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

Diformat dan dikomentari agar lebih mudah dibaca:

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

Versi ini mencetak daftar, alih-alih mencoba menemukan ikatan yang sesuai untuk suatu istilah dalam predikat.

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

Metode input

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

Sebagai catatan, ini adalah versi yang menemukan ikatan untuk memenuhi predikat:

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

Metode input

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

Revisi sebelumnya berisi solusi tidak lengkap yang tidak berhasil menghapus set kosong.


2

Mathematica 62 57 38

Kode

Input dimasukkan sebagai bilangan bulat dalam array x,.

x

memasukkan

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

Keluaran

keluaran


Penjelasan

x[[1, 1]] mengonversi input ke daftar bilangan bulat.

Subsets menghasilkan semua himpunan bagian dari bilangan bulat.

Select....Tr@# == 0 memberikan semua himpunan bagian yang memiliki total sama dengan 0.

Grid memformat himpunan bagian yang dipilih sebagai bilangan bulat yang dipisahkan ruang.


2

Jelly , 6 byte

ŒPḊSÐḟ

Cobalah online!

Hanya untuk kelengkapan. Mirip dengan Brachylog, Jelly juga memposting tantangan, tetapi sekarang, bahasa yang lebih baru bersaing secara normal.

Œ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 karakter

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

Pemakaian:

   >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

Menulis ulang kereta saat (<@":@(#~0=+/)@#"1 _~2#:@i.@^#)menyimpan 4 karakter.
algorithmshark

1

Stax , 8 byte CP437

â±3╒yΣ╓à

Jalankan dan debug online!

Penjelasan

Menggunakan versi yang belum dibongkar (9 byte) untuk menjelaskan.

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; Anda - namun - mengambil daftar sebagai input.
Jonathan Frech

Akan diperbaiki dengan biaya satu byte.
Weijun Zhou

1

J , 34 byte

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

Cobalah online!

bagaimana

".mengonversi input ke daftar. kemudian:

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

Cobalah online!

Mengembalikan daftar Tas unik dengan jumlah 0. Tas adalah Set yang berbobot.

Penjelasan:

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

Akan menambahkan tautan TIO nanti.

Mengambil input dari stdin sebagai daftar angka, mis 8 −7 5 −3 −2

Cara kerjanya: Mengkonversi input menjadi array angka. Mendapat semua permutasi dari panjang dari 1 hingga panjang array. Itu menambahkan mereka ke array output jika mereka menjumlahkan ke 0. Ini menampilkan array tanpa duplikat.

Output untuk input sampel: [[-3, -2, 5]]

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.