サブセットサム問題のゴルフ


15

仕事

入力としてスペース区切りの整数のリストを指定すると、各サブセットの合計が0になるこれらの数値の一意の空でないサブセットをすべて出力します。


テストケース

入力: 8 −7 5 −3 −2
出力:-3 -2 5


受賞基準

これはなので、バイト単位の最短コードが勝ちです!


1
入力に一意でない数値が含まれている場合、一意性について心配する必要がありますか?言い換えれば、入力のためにいくつの結果を印刷する必要があります3 3 -3 -3か?
キースランドール

@キース。慣例により、セットは最大で1回現れる個別の要素で構成されます。マルチセットには、複数回出現する要素を含めることができます。en.wikipedia.org/wiki/Multiset
DavidC

4
@ DavidCarraher、OPはリストのサブセットについて話すことにより用語を混ぜます。
ピーターテイラー

@PeterTaylorありがとう。いい視点ね。
DavidC

回答:


4

GolfScript、41文字

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

特定の出力形式を気にしない場合は、コードを33文字に短縮できます。

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

例(オンラインを参照):

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


4

Python、119文字

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

すべての2 ^ nサブセットを再帰的に列挙し、各サブセットをチェックします。


ブラボー!私はキャラクターの中に来ました
...-ブースビー

3

Python、120

私はキースのソリューションよりも悪いキャラクターです。しかし...これは投稿するには近すぎます。code-golfの私のお気に入りの機能の1つは、類似した長さのソリューションがどれほど似ていないかです。

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)

いまいましい、 itertools.permutationsそんな長い名前を持っているから!

ブルートフォースソリューション。私はそれが最短ではないことに驚いています:しかし私は推測しますitertoolsは解決策を台無しにするます。

ゴルフをしていない:

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)

ゴルフ((い出力):

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)

ゴルフ(きれいな出力)(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:itertoolsモジュールをインポートして呼び出す i

x=map(int,input().split()):入力をスペースで区切り、結果のリストの項目を整数に変換します(2 3 -5->[2, 3, -5]

(設定sorted(j)範囲内(1、i.permutationsでJ(X)であれば合計(J)== 0(X)+1)をlenが):
のすべての部分集合のリストを返しx、ソートし、ここで、和は0であり、一意のアイテム
set(...)

周りの墓( `)sorted(j)はPythonの略記ですrepr(sorted(j))。これがここにある理由は、Pythonのセットがリストを処理できないためです。したがって、テキストとしてリストを含む文字列を使用するのが次善策です。


文字列の代わりに整数を取得する方法について混乱しています。 split()文字列のリストを作成しますが、後でsumその分割のサブセットを呼び出しています。
キースランドール

@KeithRandall:facepalm急いでいたので、コードをテストしませんでした。ご指摘いただきありがとうございます。
beary605

キャラクターを保存するには、おそらくfrom itertools import*
マット

実際に墓は略記ですrepr()
ニブラー

@gnibbler: `'hello'`を実行するとき、それはより意味があります。ありがとう!
beary605

2

C#– 384文字

OK、C#での関数型プログラミングはそれほど短くはありませんが、大好きです!(ブルートフォースの列挙だけを使用して、それ以上のものはありません。)

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

読みやすくするためにフォーマットとコメントを追加:

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-プロローグ 84

このバージョンは、述語内の用語に適切なバインディングを見つけようとする代わりに、リストを出力します。

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

入力方式

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

レコードの場合、これは述語を満たすバインディングを見つけるバージョンです。

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

入力方式

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

以前のリビジョンには、空のセットを削除できなかった不完全なソリューションが含まれています。


2

Mathematica 62 57 38

コード

配列に整数として入力された入力x

x

入力

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

出力

出力


説明

x[[1, 1]] 入力を整数のリストに変換します。

Subsets 整数からすべてのサブセットを生成します。

Select....Tr@# == 0 合計が0であるすべてのサブセットを提供します。

Grid 選択したサブセットをスペース区切りの整数としてフォーマットします。


2

ゼリー、6バイト

ŒPḊSÐḟ

オンラインでお試しください!

完全を期すためだけに。Brachylogと同様に、Jellyも課題を後付けにしていますが、現在では、新しい言語は通常通り競合しています。

Œ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文字

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

使用法:

   >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

トレインを書き換えると、(<@":@(#~0=+/)@#"1 _~2#:@i.@^#)4文字節約されます。
algorithmshark 14年

1

スタックス、8 バイトCP437

â±3╒yΣ╓à

オンラインで実行してデバッグします!

説明

解凍されたバージョン(9バイト)を使用して説明します。

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; ただし、入力としてリストを取得しています。
ジョナサンフレッチ

1バイトのコストで修正されます。
ウェイジュン周

1

J、34バイト

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

オンラインでお試しください!

どうやって

".入力をリストに変換します。その後:

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バイト

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

オンラインでお試しください!

合計が0になる一意のバッグのリストを返します。バッグは重み付けされたセットです。

説明:

*.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バイト

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

後でTIOリンクを追加します。

数値のリストとして標準入力から入力を取得します。例えば 8 −7 5 −3 −2

仕組み:入力を数値の配列に変換します。1から配列の長さまでのすべての長さの順列を取得します。合計が0になると、出力配列に追加されます。重複することなく配列を出力します。

サンプル入力の出力: [[-3, -2, 5]]

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.