Golf das Teilmengen-Summen-Problem


15

Aufgabe

Geben Sie bei einer Liste von durch Leerzeichen getrennten Ganzzahlen als Eingabe alle eindeutigen nicht leeren Teilmengen dieser Zahlen aus, die jede Teilmenge mit 0 summiert.


Testfall

Eingabe: 8 −7 5 −3 −2
Ausgabe:-3 -2 5


Gewinnkriterium

Das ist , also gewinnt der kürzeste Code in Bytes!


1
Müssen wir uns um die Eindeutigkeit sorgen, wenn die Eingabe nicht eindeutige Zahlen enthält? Mit anderen Worten, wie viele Ergebnisse muss ich für die Eingabe drucken 3 3 -3 -3?
Keith Randall

@ Keith. Gemäß der Konvention bestehen Mengen aus unterschiedlichen Elementen, die höchstens einmal auftreten. Multisets können Elemente enthalten, die mehrmals vorkommen. en.wikipedia.org/wiki/Multiset
DavidC

4
@DavidCarraher, OP mischt die Terminologie, indem es über Teilmengen von Listen spricht.
Peter Taylor

@ PeterTaylor Danke. Guter Punkt.
DavidC

Antworten:


4

GolfScript, 41 Zeichen

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

Wenn Sie sich nicht für das jeweilige Ausgabeformat interessieren, können Sie den Code auf 33 Zeichen kürzen.

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

Beispiel (siehe online ):

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


4

Python, 119 Zeichen

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

Listet alle 2 ^ n Teilmengen rekursiv auf und überprüft jede.


Bravo! Ich kam innerhalb eines Charakters ...
Stand vom

3

Python, 120

Ich bin ein schlechterer Charakter als Keith. Aber ... das ist zu nah, um es nicht zu posten. Eines meiner Lieblingsmerkmale von Code-Golf ist, wie unterschiedlich Lösungen mit ähnlicher Länge sein können.

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)

Verdammt, dass du itertools.permutationsso einen langen Namen hast !

Brute-Force-Lösung. Ich bin überrascht, dass es nicht die kürzeste ist, aber ich vermute, dass sie itertoolsdie Lösung ruiniert.

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)

Golf (hässliche Leistung):

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 (ziemlich gute Leistung) (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: Importieren des itertools-Moduls und Aufrufen i

x=map(int,input().split()): trennt die Eingabe durch Leerzeichen und wandelt dann die Elemente der resultierenden Listen in Ganzzahlen um (2 3 -5 -> [2, 3, -5])

set ( sorted(j)für a in range (1, len (x) +1) für j in i.permutations (x, a), wenn summe (j) == 0):
Gibt eine Liste aller Teilmengen in xsortiert zurück, wobei die Summe ist 0 und erhält dann nur die eindeutigen Elemente
( set(...))

Bei den Gräbern (`) handelt es sich um die sorted(j)Abkürzung für Python repr(sorted(j)). Der Grund dafür ist, dass Sets in Python keine Listen verarbeiten können. Daher ist es am besten, Zeichenfolgen mit einer Liste als Text zu verwenden.


Ich bin verwirrt darüber, wie Sie Ganzzahlen anstelle von Zeichenfolgen erhalten. split()erstellt eine Liste von Zeichenfolgen, aber später rufen Sie sumdie Teilmengen dieser Teilung auf.
Keith Randall

@KeithRandall: facepalm Ich war in Eile, also habe ich meinen Code nicht getestet. Danke, dass Sie darauf hingewiesen haben.
beary605

Sie können wahrscheinlich einen Charakter speichern, indem Sie Folgendes tunfrom itertools import*
Matt

Eigentlich ist das Grab Abkürzung fürrepr()
Knabber

@gnibbler: Das wäre viel sinnvoller, wenn man `'hallo' 'ausführen würde. Vielen Dank!
beary605

2

C # - 384 Zeichen

OK, funktionales Programmieren in C # ist nicht so kurz , aber ich liebe es! (Mit nur einer Brute-Force-Aufzählung, nichts Besseres.)

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

Zur besseren Lesbarkeit formatiert und kommentiert:

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

Diese Version gibt die Liste aus, anstatt zu versuchen, eine geeignete Bindung für einen Begriff in einem Prädikat zu finden.

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

Eingabe Methode

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

Für den Datensatz ist dies die Version, die eine Bindung findet, um das Prädikat zu erfüllen:

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

Eingabe Methode

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

Die vorherige Version enthält eine unvollständige Lösung, bei der es nicht gelungen ist, leere Sätze zu entfernen.


2

Mathematica 62 57 38

Code

Eingabe eingegeben als ganze Zahlen in einem Array x.

x

Eingang

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

Ausgabe

Ausgabe


Erläuterung

x[[1, 1]] konvertiert die Eingabe in eine Liste von Ganzzahlen.

Subsets generiert alle Teilmengen aus den ganzen Zahlen.

Select....Tr@# == 0 gibt alle Untermengen mit einer Summe von 0 an.

Grid formatiert die ausgewählten Teilmengen als durch Leerzeichen getrennte Ganzzahlen.


2

Gelee , 6 Bytes

ŒPḊSÐḟ

Probieren Sie es online!

Nur der Vollständigkeit halber. Ähnlich wie Brachylog gibt auch Jelly die Herausforderung bekannt, aber inzwischen konkurrieren neuere Sprachen 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 Zeichen

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

Verwendung:

   >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

Das Umschreiben des Zuges (<@":@(#~0=+/)@#"1 _~2#:@i.@^#)speichert 4 Zeichen.
Algorithmushai

1

Stax , 8 Bytes CP437

â±3╒yΣ╓à

Online ausführen und debuggen!

Erläuterung

Verwendet die entpackte Version (9 Bytes), um zu erklären.

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; Sie nehmen jedoch eine Liste als Eingabe.
Jonathan Frech

Wird auf Kosten eines Bytes behoben.
Weijun Zhou

1

J , 34 Bytes

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

Probieren Sie es online!

Wie

".wandelt die Eingabe in eine Liste um. dann:

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 Bytes

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

Probieren Sie es online!

Gibt eine Liste einzigartiger Taschen zurück, die sich zu 0 summieren. Eine Tasche ist ein gewichtetes Set.

Erläuterung:

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

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

Fügt später einen TIO-Link hinzu.

Übernimmt die Eingabe von stdin als Liste von Zahlen, z 8 −7 5 −3 −2

Wie es funktioniert: Es konvertiert die Eingabe in ein Array von Zahlen. Ruft alle Permutationen der Längen von 1 bis zur Länge des Arrays ab. Sie werden dem Ausgabearray hinzugefügt, wenn sie eine Summe von 0 ergeben. Das Array wird ohne Duplikate ausgegeben.

Ausgabe für die Beispieleingabe: [[-3, -2, 5]]

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.