任务
给定以空格分隔的整数列表作为输入,请输出这些数字的所有唯一非空子集,每个子集的总和为0。
测试用例
输入: 8 −7 5 −3 −2
输出:-3 -2 5
获胜标准
这是代码高尔夫球,因此以字节为单位的最短代码胜出!
给定以空格分隔的整数列表作为输入,请输出这些数字的所有唯一非空子集,每个子集的总和为0。
输入: 8 −7 5 −3 −2
输出:-3 -2 5
这是代码高尔夫球,因此以字节为单位的最短代码胜出!
Answers:
你该死的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]
)
set(sorted(j)
for a in range(1,len(x)+1)for i in i.permutations(x,a)if sum(j)== 0):
返回x
,排序的所有子集的列表,其中和为0,然后仅获取唯一项
(set(...)
)
周围的坟墓(`)sorted(j)
是Python的缩写repr(sorted(j))
。之所以这样,是因为Python中的集合无法处理列表,因此,下一个最好的方法是使用带有列表的字符串作为文本。
split()
创建一个字符串列表,但是稍后您需要调用sum
该拆分的子集。
from itertools import*
repr()
好的,用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);
}
}
此版本打印列表,而不是尝试为谓词中的术语找到适当的绑定。
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).
先前的版本包含一个不完整的解决方案,该解决方案无法删除空集。
>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个字符。
(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.
*.words.combinations.skip.grep(!*.sum)>>.Bag.unique
返回总计为0的唯一Bags的列表。Bag是加权Set。
*.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
3 3 -3 -3
?