Golf il problema della somma dei sottoinsiemi


15

Compito

Dato un elenco di numeri interi delimitati da spazi come input, genera tutti i sottoinsiemi non vuoti univoci di questi numeri che ogni sottoinsieme somma a 0.


Caso di prova

Ingresso: 8 −7 5 −3 −2
Uscita:-3 -2 5


Criterio vincente

Questo è , quindi vince il codice più corto in byte!


1
Dobbiamo preoccuparci dell'unicità se l'input contiene numeri non univoci? In altre parole, quanti risultati devo stampare per l'input 3 3 -3 -3?
Keith Randall,

@Keith. Per convenzione, gli insiemi sono costituiti da elementi distinti che appaiono al massimo una volta. I multiset possono avere elementi che appaiono più di una volta. en.wikipedia.org/wiki/Multiset
DavidC

4
@DavidCarraher, OP mescola la terminologia parlando di sottoinsiemi di elenchi.
Peter Taylor,

@PeterTaylor Grazie. Buon punto.
DavidC,

Risposte:


4

GolfScript, 41 caratteri

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

Se non ti interessa il formato di output specifico, puoi abbreviare il codice a 33 caratteri.

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

Esempio (vedi online ):

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

6

Brachylog (2), 9 caratteri

{⊇.+0∧}ᵘb

Provalo 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 caratteri

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

Enumera ricorsivamente tutti i 2 ^ n sottoinsiemi e li controlla ciascuno.


Bravo! Sono entrato in un personaggio ...
stand dal

3

Python, 120

Sono un personaggio peggiore della soluzione di Keith. Ma ... questo è troppo vicino per non pubblicare. Una delle mie caratteristiche preferite del code-golf è quanto possano essere diverse soluzioni di lunghezza simile.

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)

Accidenti a te, itertools.permutationsper avere un nome così lungo!

Soluzione di forza bruta. Sono sorpreso che non sia il più breve: ma immagino itertoolsrovina la soluzione.

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 (uscita brutta):

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 (bella uscita) (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: importando il modulo itertools e chiamandolo i

x=map(int,input().split()): separa l'input per spazi, quindi trasforma gli elementi degli elenchi risultanti in numeri interi ( 2 3 -5-> [2, 3, -5])

set ( sorted(j)per a in range (1, len (x) +1) per j in i.permutations (x, a) se sum (j) == 0):
restituisce un elenco di tutti i sottoinsiemi in x, ordinati, in cui la somma è 0, quindi ottiene solo gli elementi univoci
( set(...))

The graves (`) around sorted(j)è la scorciatoia di Python per repr(sorted(j)). Il motivo per cui questo è qui è perché gli insiemi in Python non possono gestire gli elenchi, quindi la cosa migliore è usare stringhe con un elenco come testo.


Sono confuso su come stai ottenendo numeri interi anziché stringhe. split()crea un elenco di stringhe, ma poi in seguito stai chiamando sumi sottoinsiemi di quella divisione.
Keith Randall,

@KeithRandall: facepalm Ero di fretta, quindi non ho testato il mio codice. Grazie per averlo sottolineato.
beary605,

Probabilmente puoi salvare un personaggio facendofrom itertools import*
Matt

in realtà la tomba è una scorciatoia perrepr()
gnibbler

@gnibbler: Ciò avrebbe molto più senso quando si esegue `` ciao ''. Grazie!
beary605,

2

C # - 384 caratteri

OK, la programmazione in stile funzionale in C # non è così breve , ma la adoro ! (Usando solo un elenco di forza bruta, niente di meglio.)

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

Formattato e commentato per una maggiore leggibilità:

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

Questa versione stampa l'elenco, invece di cercare di trovare un'associazione appropriata per un termine in un predicato.

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

Metodo di input

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

Per la cronaca, questa è la versione che trova un'associazione per soddisfare il predicato:

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

Metodo di input

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

La revisione precedente contiene una soluzione incompleta che non è riuscita a rimuovere il set vuoto.


2

Mathematica 62 57 38

Codice

Ingresso è entrata come numeri interi in un array, x.

x

ingresso

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

Produzione

produzione


Spiegazione

x[[1, 1]] converte l'input in un elenco di numeri interi.

Subsets genera tutti i sottoinsiemi dagli interi.

Select....Tr@# == 0 fornisce tutti quei sottoinsiemi che hanno un totale pari a 0.

Grid formatta i sottoinsiemi selezionati come numeri interi separati da spazio.


2

Gelatina , 6 byte

ŒPḊSÐḟ

Provalo online!

Solo per completezza. Simile a Brachylog, anche Jelly ha postdatato la sfida, ma ormai le nuove lingue competono normalmente.

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

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

Uso:

   >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

Riscrivere il treno per (<@":@(#~0=+/)@#"1 _~2#:@i.@^#)salvare 4 caratteri.
algoritmo


1

J , 34 byte

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

Provalo online!

Come

".converte l'input in un elenco. poi:

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

Provalo online!

Restituisce un elenco di Borse uniche che si sommano a 0. Una Borsa è un Set ponderato.

Spiegazione:

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

Rubino, 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

Aggiungerà il collegamento TIO più tardi.

Prende input da stdin come un elenco di numeri, ad es 8 −7 5 −3 −2

Come funziona: converte l'input in una matrice di numeri. Ottiene tutte le permutazioni delle lunghezze da 1 alla lunghezza dell'array. Li aggiunge all'array di output se sommano a 0. Emette l'array senza duplicati.

Uscita per l'ingresso campione: [[-3, -2, 5]]

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.