Golf le problème du sous-ensemble


15

Tâche

Étant donné une liste d'entiers séparés par des espaces en entrée, sortez tous les sous-ensembles non vides uniques de ces nombres que chaque sous-ensemble additionne à 0.


Cas de test

Entrée: 8 −7 5 −3 −2
Sortie:-3 -2 5


Critère gagnant

C'est le , donc le code le plus court en octets gagne!


1
Devons-nous nous soucier de l'unicité si l'entrée contient des nombres non uniques? En d'autres termes, combien de résultats dois-je imprimer pour l'entrée 3 3 -3 -3?
Keith Randall

@Keith. Par convention, les ensembles sont constitués d'éléments distincts qui apparaissent au plus une fois. Les multi-ensembles peuvent avoir des éléments qui apparaissent plusieurs fois. en.wikipedia.org/wiki/Multiset
DavidC

4
@DavidCarraher, OP mélange la terminologie en parlant de sous-ensembles de listes.
Peter Taylor

@PeterTaylor Merci. Bon point.
DavidC

Réponses:


4

GolfScript, 41 caractères

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

Si vous ne vous souciez pas du format de sortie spécifique, vous pouvez raccourcir le code à 33 caractères.

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

Exemple (voir en ligne ):

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

6

Brachylog (2), 9 caractères

{⊇.+0∧}ᵘb

Essayez-le en ligne!

{⊇.+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 caractères

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

Énumère récursivement tous les 2 ^ n sous-ensembles et vérifie chacun d'eux.


Bravo! Je suis venu dans un personnage ...
Boothby

3

Python, 120

Je suis un personnage pire que la solution de Keith. Mais ... c'est trop proche pour ne pas poster. L'une de mes caractéristiques préférées du code-golf est la diversité des solutions de longueur similaire.

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)

Merde itertools.permutations, pour avoir un nom si long!

Solution de force brute. Je suis surpris que ce ne soit pas le plus court: mais je suppose que cela itertoolsgâche la solution.

Non golfé:

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é (sortie moche):

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é (jolie sortie) (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: importer le module itertools et l'appeler i

x=map(int,input().split()): sépare l'entrée par des espaces, puis transforme les éléments des listes résultantes en entiers ( 2 3 -5-> [2, 3, -5])

set ( sorted(j)for a in range (1, len (x) +1) for j in i.permutations (x, a) if sum (j) == 0):
Renvoie une liste de tous les sous-ensembles x, triés, où la somme est 0, puis obtient uniquement les éléments uniques
( set(...))

Les tombes (`) autour sorted(j)sont un raccourci en Python pour repr(sorted(j)). La raison pour laquelle ceci est ici est que les ensembles en Python ne peuvent pas gérer les listes, donc la meilleure chose à faire est d'utiliser des chaînes avec une liste comme texte.


Je ne sais pas comment vous obtenez des entiers au lieu de chaînes. split()fait une liste de chaînes, mais plus tard, vous appelez sumles sous-ensembles de cette division.
Keith Randall

@KeithRandall: facepalm J'étais pressé, donc je n'ai pas testé mon code. Merci d'avoir fait remarquer cela.
beary605

Vous pouvez probablement sauver un personnage en faisantfrom itertools import*
Matt

en fait, les tombes sont un raccourci pourrepr()
gnibbler

@gnibbler: Cela aurait beaucoup plus de sens lors de l'exécution de `` bonjour ''. Merci!
beary605

2

C # - 384 caractères

OK, la programmation de style fonctionnel en C # n'est pas si courte , mais j'adore ! (En utilisant juste une énumération par force brute, rien de mieux.)

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

Formaté et commenté pour plus de lisibilité:

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

Cette version imprime la liste, au lieu d'essayer de trouver une liaison appropriée pour un terme dans un prédicat.

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

Procédé d'entrée

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

Pour mémoire, il s'agit de la version qui trouve une liaison pour satisfaire le prédicat:

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

Procédé d'entrée

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

La révision précédente contient une solution incomplète qui n'a pas réussi à supprimer l'ensemble vide.


2

Mathematica 62 57 38

Code

Entrée est entré en tant que nombres entiers dans un tableau, x.

x

contribution

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

Production

production


Explication

x[[1, 1]] convertit l'entrée en une liste d'entiers.

Subsets génère tous les sous-ensembles à partir des entiers.

Select....Tr@# == 0 donne tous les sous-ensembles dont le total est égal à 0.

Grid formate les sous-ensembles sélectionnés sous forme d'entiers séparés par des espaces.


2

Gelée , 6 octets

ŒPḊSÐḟ

Essayez-le en ligne!

Juste pour être complet. Semblable à Brachylog, Jelly remonte également le défi, mais à l'heure actuelle, les nouvelles langues rivalisent normalement.

Œ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 caractères

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

Usage:

   >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

La réécriture du train (<@":@(#~0=+/)@#"1 _~2#:@i.@^#)enregistre 4 caractères.
algorithmshark


1

J , 34 octets

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

Essayez-le en ligne!

Comment

".convertit l'entrée en une liste. ensuite:

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 octets

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

Essayez-le en ligne!

Renvoie une liste de sacs uniques totalisant 0. Un sac est un ensemble pondéré.

Explication:

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

Rubis, 110 octets

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

Ajoutera un lien TIO plus tard.

Prend l'entrée de stdin comme une liste de nombres, par exemple 8 −7 5 −3 −2

Comment ça marche: Il convertit l'entrée en un tableau de nombres. Obtient toutes les permutations des longueurs de 1 à la longueur du tableau. Il les ajoute au tableau de sortie s'ils totalisent 0. Il génère le tableau sans doublons.

Sortie pour l'entrée échantillon: [[-3, -2, 5]]

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.