Golf o problema da soma de subconjuntos


15

Tarefa

Dada uma lista de números inteiros delimitados por espaço como entrada, produza todos os subconjuntos não vazios exclusivos desses números que cada subconjunto soma a 0.


Caso de teste

Entrada: 8 −7 5 −3 −2
Saída:-3 -2 5


Critério vencedor

Isso é , então o código mais curto em bytes vence!


1
Precisamos nos preocupar com exclusividade se a entrada contiver números não exclusivos? Em outras palavras, quantos resultados tenho para imprimir para a entrada 3 3 -3 -3?
Keith Randall

@Keith. Por convenção, os conjuntos consistem em elementos distintos que aparecem no máximo uma vez. Múltiplas configurações podem ter elementos que aparecem mais de uma vez. pt.wikipedia.org/wiki/Multiset
DavidC 10/10

4
@DavidCarraher, OP mistura terminologia falando sobre subconjuntos de listas.
22412 Peter Taylor

@PeterTaylor Thanks. Bom ponto.
10133

Respostas:


4

GolfScript, 41 caracteres

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

Se você não se importa com o formato de saída específico, pode encurtar o código para 33 caracteres.

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

Exemplo (consulte online ):

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

6

Brachylog (2), 9 caracteres

{⊇.+0∧}ᵘb

Experimente 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 caracteres

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 todos os subconjuntos 2 ^ n recursivamente e verifica cada um.


Bravo! Eu vim dentro de um personagem ... #
101012

3

Python, 120

Sou um personagem pior que a solução de Keith. Mas ... isso está muito perto para não postar. Um dos meus recursos favoritos do code-golf é o quão diferentes soluções de comprimento semelhante podem ser.

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

Maldito, itertools.permutations por ter um nome tão longo!

Solução de força bruta. Estou surpreso que não seja o mais curto: mas achoitertools estraga a solução.

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)

Golfe (saída feia):

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)

Golfe (saída bonita) (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 o módulo itertools e chamando-o i

x=map(int,input().split()): separa a entrada por espaços e transforma os itens das listas resultantes em números inteiros ( 2 3 -5-> [2, 3, -5])

set ( sorted(j)para um no intervalo (1, len (x) +1) para j em i.permutations (x, a) if sum (j) == 0):
Retorna uma lista de todos os subconjuntos em x, classificados, onde a soma é 0 e, em seguida, obtém apenas os itens exclusivos
( set(...))

Os túmulos (`) ao redor sorted(j)são uma abreviação para Python repr(sorted(j)). A razão pela qual isso está aqui é porque os conjuntos no Python não podem manipular listas, então a próxima melhor coisa é usar cadeias com uma lista como texto.


Estou confuso sobre como você está obtendo números inteiros em vez de strings. split()faz uma lista de seqüências de caracteres, mas depois você está chamando sumos subconjuntos dessa divisão.
Keith Randall

@KeithRandall: facepalm Eu estava com pressa, então não testei meu código. Obrigado por apontar isso.
beary605

Você provavelmente pode salvar um personagem fazendofrom itertools import*
Matt

na verdade, as sepulturas é uma abreviação pararepr()
gnibbler

@gnibbler: Isso faria muito mais sentido ao executar `` hello ''. Obrigado!
beary605

2

C # - 384 caracteres

OK, a programação de estilo funcional em C # não é tão curta , mas eu adoro ! (Usando apenas uma enumeração de força bruta, nada melhor.)

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

Formatado e comentado para mais legibilidade:

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

Esta versão imprime a lista, em vez de tentar encontrar uma ligação apropriada para um termo em um predicado.

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

Método de entrada

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

Para o registro, esta é a versão que encontra uma ligação para satisfazer o predicado:

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

Método de entrada

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

A revisão anterior contém uma solução incompleta que não conseguiu remover o conjunto vazio.


2

Mathematica 62 57 38

Código

Entrada inserida como números inteiros em uma matriz x,.

x

entrada

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

Resultado

resultado


Explicação

x[[1, 1]] converte a entrada em uma lista de números inteiros.

Subsets gera todos os subconjuntos dos números inteiros.

Select....Tr@# == 0 fornece todos os subconjuntos que possuem um total igual a 0.

Grid formata os subconjuntos selecionados como números inteiros separados por espaço.


2

Gelatina , 6 bytes

ŒPḊSÐḟ

Experimente online!

Apenas por completude. Semelhante ao Brachylog, o Jelly também pós o desafio, mas agora os idiomas mais novos competem 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 caracteres

>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

Reescrever o trem como (<@":@(#~0=+/)@#"1 _~2#:@i.@^#)salva 4 caracteres.
algorithmshark

1

Stax , 8 bytes CP437

â±3╒yΣ╓à

Execute e depure online!

Explicação

Usa a versão descompactada (9 bytes) para explicar.

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; você está - no entanto - tomando uma lista como entrada.
Jonathan Frech

Fixará ao custo de um byte.
Weijun Zhou

1

J , 34 bytes

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

Experimente online!

como

".converte a entrada em uma lista. então:

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

Experimente online!

Retorna uma lista de sacos exclusivos que somam 0. Um saco é um conjunto ponderado.

Explicação:

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

Adicionará o link do TIO posteriormente.

Recebe a entrada do stdin como uma lista de números, por exemplo 8 −7 5 −3 −2

Como funciona: converte a entrada em uma matriz de números. Obtém todas as permutações dos comprimentos de 1 ao comprimento da matriz. Ele os adiciona à matriz de saída se eles somam a 0. Ele gera a matriz sem duplicatas.

Saída para a entrada de amostra: [[-3, -2, 5]]

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.