它是无和集吗?


32

如果集合中没有两个(不一定是不同的)元素在一起,则该集合是不求和的。

例如,{1, 5, 7}是无和的,因为所有成员都是奇数,并且两个奇数加在一起时总是偶数。在另一方面,{2, 4, 9, 13}不是免费求和,如任一2 + 2 = 44 + 9 = 13一起添加到该组的一个成员。

编写一个将集合作为输入的程序或函数,如果集合不加和,则输出True值,否则输出Falsy。

例子:

Sum-free:
{}
{4}
{1, 5, 7}
{16, 1, 4, 9}

Not sum-free:
{0}
{1, 4, 5, 7}
{3, 0}
{16, 1, 4, 8}

该集合可以是数组/列表吗?
科纳·奥布莱恩

@CᴏɴᴏʀO'Bʀɪᴇɴ好的。
orlp 2016年

5
一些更多的测试用例可能很好!
林恩

4
急需测试用例。套装纯粹是唯一的吗?

3
我认为您应该澄清一下,是指集合中两个不一定不同的元素之和。
Gregory Nisbet

Answers:


14

Pyth- 8 5个字节

感谢@FryAmTheEggman为我节省了3个字节。

!@sM*

测试套件

!             Logical not. This makes the empty intersection true and vice versa.
 @    Q       Setwise intersection with input (implictly).
  sM          Map sum to all the pairs.
   *QQ        Get all pairs by doing cartesian product with input*input (implicit).

@FryAmTheEggman智能....
Maltysen

我只是得到了相同的答案,但后来意识到* QQ实际上产生了[1,1],这是两个相同的元素,不应出现在地图中。
busukxuan '16

@busukxuan问题实际上要求您考虑重复:2 + 2 = 4从OP。FryAmTheEggman高尔夫之前我的回答实际使用.Combinations 与更换,因为这一点。
Maltysen '16

@Maltysen哦,太好了!
busukxuan '16

40

Python 2,41个字节

lambda s:s==s-{a+b for a in s for b in s}

s 应该是Python集。

有趣的事实:sum-free是我名字的一个字谜。


lambda s:not{a+b for a in s for b in s}&s长度相同 不幸的是,我找不到缩短这种否定的方法。
FryAmTheEggman'7

16
为字谜而投票。
尼尔

@feersum这是您的问题。
Filip Haglund

@FilipHaglund不,是奥尔普的。
mbomb007'7

@ mbomb007如果严重,是的。但是,这可能有一个不严重的含义:这是您的问题/您不知道这个问题/您在这里击败了其他所有人(Python)。他们没有说“ OP”
暴民埃里克

26

果冻,5 个字节

ṗ3ḅ-P

在线尝试!

怎么运行的

ṗ3ḅ-P  Main link. Argument: A (array)

ṗ3     Take the third Cartesian power of A, i.e., generate all triplets that
       consist of elements of A.
  ḅ-   Convert each triplet from base -1 to integer.
       This maps [a, b, c] to a - b + c = (a + c) - b.
       If (a + c) belong to A, this will yield 0 for some b.
    P  Take the product of all resulting integers. 

13

JavaScript,86 42 41字节

n=>!n.some(m=>n.some(o=>n.includes(m+o)))

感谢C'O'Bʀɪᴇɴ为我从括号/弯括号中节省了很多字节。同样感谢Neil指出该函数返回的布尔值与其应有的值相反。

我试图通过重新定义来减少字节数,n.some但这不起作用,因为不幸的是它是原型函数。Array.prototype.map在JS中可能有更好的解决方案,但是some函数确实很有趣。

我现在想知道是否有比.includes使用诸如.indexOf 之类的方法更短的方法,并加1(如果包含数字,它将得到真实的值)。


测试:

> (n=>!n.some(m=>n.some(o=>n.includes(m+o))))([1,5,7]);
true
> (n=>!n.some(m=>n.some(o=>n.includes(m+o))))([1,5,7,12]);
false

1
试试n=>n.some(m=>n.some(o=>n.some(p=>m+o==p)))
Conor O'Brien

1
没问题!它的工作是由于匿名函数的行为。看看这里的其他ES6答案,您会学到很多:)
Conor O'Brien

1
您好,欢迎来到PPCG!
NoOneIsHere

1
这种感觉是错误的,它告诉您集合是否不是无和的。另外,使用n.contains(o+p)可以在最里面节省2个字节some
尼尔

1
抱歉,是的,我的意思是includes(它原本会被调用,contains但是某些库的定义有冲突)。
尼尔

12

MATL,5个字节

t&+m~

如果所有条目均为true,则输出一个数组,1否则为false。这是演示如何在MATL中显示各种真假值的演示

在线尝试

说明

        % Implicitly grab input
t       % Duplicate
&+      % Compute sum of each element with every other element (2D Matrix)
m       % Check which members of the input are present in this matrix of sums
~       % Negate the result to yield a truthy value for sum-free sets
        % Implicitly display truthy/falsey value

12

Mathematica,23字节

{}==#⋂Tr/@#~Tuples~2&

我错误地编辑了您的提交内容,但后来又回到了原来的状态。抱歉!
DavidC

顺便说一句,很好的见解是在制作元组之前不必从列表中删除任何元素。
DavidC

1
请更换(U-22C2)。目前该代码不可复制到Mathematica中。
LLlAMnYP'7

@LLlAMnYP谢谢,我不得不手动查找Unicode字符,因为Mathematica在复制表达式时会自动设置其格式;我一定找到了错误的那个。
西蒙斯(Simmons)

1
@ASimmons如果您在Mathematica中突出显示该字符并单击F1,它将为您显示该特定字符的帮助页面,该页面始终包含该字符的Unicode代码点(以十六进制表示)。尽管您不能仅将其复制为Unicode,但这确实很烦人。我认为在Mathematica.SE的某处有一种“将Unicode复制”的解决方案,但IIRC绝非易事。
Martin Ender

11

Haskell中,32,30个字节

简单的解决方案:

f x=and[a+b/=c|a<-x,b<-x,c<-x]

@Lynn保存了两个字节


f x=and[a+b/=c|a<-x,b<-x,c<-x]30个字节。
林恩


6

J,18 10 8字节

多亏了英里,节省了8个字节,而多亏了FrownyFrog,节省了2个字节!

-:]-.+/~

将原始列表与列表和的设定差相匹配。这等效于:

(-: (] -. +/~)) y

供输入y。转换为:

y -: (] -. +/~) y
y -: (y -. +/~ y)

+/~使用返回一个汇总表y。对于y =: 16 1 4 9,这给出:

   +/~ 16 1 4 9
32 17 20 25
17  2  5 10
20  5  8 13
25 10 13 18

然后,我们使用-.,它会产生一个包含y此表中未包含的所有元素的列表。如果列表不加总和,则将产生相同的列表。然后,-:检查列表是否相等,从而产生所需的输出。

旧的18字节

[:-.[:>./^:_+/~e.]

+/~创建一个添加到自身的集合值的表,并e.检查这些成员是否在原始集合中。剩下的就是否定最大元素。


-:]-.&,+/~使用设置差异-.和列表匹配获取10个字节-:
英里

哦,非常好!
科纳·奥布莱恩

您不需要&,-.已经可以处理y的单元格了。
FrownyFrog

@FrownyFrog令人着迷,蒂尔。谢谢!
科纳·奥布莱恩

5

视网膜45 44字节

\d+
<$&$*1>
$
$`$`
M`(<1*)>.*<(1*>).*\1\2
^0

输入是用逗号分隔的数字的十进制列表。输出为0(虚假)或1(真实)。

在线尝试!(第一行启用换行分隔的测试套件。)

说明

阶段1:替代

\d+
<$&$*1>

这会将输入的所有元素转换为一元并将其包装在中<...>。尖括号的目的是将一个仅包含列表0与一个空列表区分开(因为的一元表示0本身是空的)。

第二阶段:替代

$
$`$`

我们将字符串重复3次,最后添加两次。

第三阶段:比赛

M`(<1*)>.*<(1*>).*\1\2

现在,我们尝试在结果中找到三个数字,以使前两个加起来成为第三个。那些匹配被计算在内(这实际上并不计算所有这样的元组,因为匹配不能重叠,但是如果存在这样的元组,则会找到它)。因此,我们得到0无和集,否则得到正数。

阶段4:比赛

^0

由于上一阶段给出了与我们想要的相反的结果,因此我们通过计算匹配项^01用于输入00其他所有项)的匹配来求反。


5

八度,29 21 25字节

@(s)~[ismember(s,s+s') 0]

感谢Suever!它返回一个数组。我0在末尾添加以使[]总和变得免费。要在Octave中验证真假,可以执行以下操作:

> f=@(s)~[ismember(s,s+s') 0]

> if f([]) "sum-free" else "not sum-free" end
ans = sum-free

> if f([0]) "sum-free" else "not sum-free" end
ans = not sum-free

> if f([4]) "sum-free" else "not sum-free" end
ans = sum-free

> if f([1 3]) "sum-free" else "not sum-free" end
ans = sum-free

> if f([2 4]) "sum-free" else "not sum-free" end
ans = not sum-free

返回0或1的替代方法是:

@(s)~numel(intersect(s+s',s))

您可以将其更改为@(s)~ismember(s+s',s)因为数组可以是真/假
Suever 2016年

5

Clojure,47 37字节

#(=(for[a % b % :when(%(+ a b))]a)[])

很简单的解决方案。使用列表推导来查找总和等于另一个元素的所有元素。

38个字节的变体:

#(every? nil?(for[a % b %](%(+ a b))))

1
由于在挑战中您将集合作为输入,因此您可以简单地使用集合检查成员资格,因为#(=(for[a % b % :when(%(+ a b))]a)[])这样可以节省10个字节
英里

@miles哦,哇,谢谢,我确实忽略了这个事实并使用了列表。
悬崖根

4

Perl 6的 24 21 20  19个字节

{not any (@_ X+@_)X==@_}
{so all (@_ X+@_)X!==@_}
{not @_ (&)(@_ X+@_)}
{not @_∩(@_ X+@_)}

{!(@_∩(@_ X+@_))}

输入是任何位置值,例如List
集合关联的,因此您必须对其进行调用.keys。)

测试:

#! /usr/bin/env perl6
use v6.c;
use Test;

my @sum-free = (
  (),
  (4,),
  (1, 5, 7),
  (16, 1, 4, 9),
);

my @not-sum-free = (
  (0,),
  (1, 4, 5, 7),
  (3, 0),
  (16, 1, 4, 8),
);

my @tests = ( |(@sum-free X=> True), |(@not-sum-free X=> False) );

plan +@tests;

# store the lambda in lexical namespace for clarity
my &sum-free-set = {!(@_∩(@_ X+@_))}

for @tests -> $_ ( :key(@list), :value($expected) ) {
  is sum-free-set(@list), $expected, .gist
}
1..8
ok 1 - () => True
ok 2 - (4) => True
ok 3 - (1 5 7) => True
ok 4 - (16 1 4 9) => True
ok 5 - (0) => False
ok 6 - (1 4 5 7) => False
ok 7 - (3 0) => False
ok 8 - (16 1 4 8) => False

4

Mathematica 63 62 42字节

此较短的版本得益于A Simmons的提交。在IntegerPartitions应用之前,无需从列表中删除任何元素。

如果一个元素不能划分为两个整数(列表中的每个整数),则IntegerPartitions[#,{2},#]=={}成立。 And检查这是否适用于列表中的每个元素。如果是这样,则该列表不包含和。

And@@(IntegerPartitions[#,{2},#]=={}&/@#)&

例子

 And@@(IntegerPartitions[#,{2},#]=={}&/@ #)&@{2, 4, 9, 13}


 And@@(IntegerPartitions[#,{2},#]=={}&/@ #)&@{1, 5, 7}

真正


有2,但没有奇数相差2。

 And@@(IntegerPartitions[#,{2},#]=={}&/@#)&@{2, 3, 7, 11, 17, 23, 29, 37, 41, 47, 53, 59, 67, 71}

真正


您是否a在工作簿中定义了其他地方?当我评估它们时,这些表达式无法提供所需的输出。
西蒙斯(Simmons)

谢谢。那a应该是一个#。我纠正了这个问题,并删除了多余的部分@
DavidC 2016年

3

Ruby,36个字节

针对自身构造该集合的笛卡尔积,并找到所有元素的总和,然后检查与原始集合的交集。输入是数组,但是在Ruby中,它们有足够的set操作来使它无论如何都能很好地工作。

由于@feersum的启发,我的原始解决方案-1字节(用于&代替,-并与进行比较[]

在这里尝试!

->s{s-s.product(s).map{|x,y|x+y}==s}

3

Python,40个字节

lambda s:s^{a+b for a in s for b in s}>s

^ =对称差,新集合中任一集合中都有元素,但不是两个

> 如果左集合是右集合的超集,则为true。


这对于空集不起作用,尽管我不知道这是否是必需的。
xnor

1
好吧,维基百科(除其他外)说 A is sum-free if the equation a + b = c has no solution with a, b, c ∈ A。用这个定义,空集不是免费的,我的回答是正确的。但是我可能有偏见。
Lulhum '16

3
该定义表示空集是无和的,因为空集中没有满足该方程的a,b和c。OP的新增测试用例对此提供了支持。
丹尼斯

3

Brachylog,13个字节

'(p:?+L:?x'L)

说明

'(          )  True if what's in the parentheses is impossible, false otherwise
  p            Get a permutation of Input
   :?+L        L is the list of element-wise sums of the permutation with Input
       :?x'L   There is at least one element of Input in L

[2:2]2个元素的子集[2:4:9]吗?
Leaky Nun

@LeakyNun不,因为2仅在中出现一次[2:4:9]
致命

3

R,39 36字节

w<-function(s)!any(outer(s,s,'+')%in%s)

称为w(s),其中s是值的集合(实际上是向量)。这是一些测试用例的输出:

> w(numeric(0)) # The empty set
[1] TRUE
> w(0)
[1] FALSE
> w(1)
[1] TRUE
> w(c(1, 5, 7))
[1] TRUE
> w(c(2, 4, 9, 13))
[1] FALSE

c()串联函数在哪里,它采用一堆值并将其设为向量。

编辑:感谢@MickyT,使其成为保存3个字节的匿名函数。

function(s)!any(outer(s,s,'+')%in%s)

非常好。如果愿意,可以将它们发布为未命名的函数。这样可以节省3个字节。例如function(s)!any(outer(s,s,'+')%in%s)
MickyT '16

3

球拍,58字节

(λ(l)(andmap(λ(m)(andmap(λ(n)(not(memq(+ n m)l)))l))l))

说明:

(λ(l)(andmap(λ(m)(andmap(λ(n)(not(memq(+ n m)l)))l))l))
(λ(l)                                                 ) # Define a lambda function that takes in one parameter
     (andmap(λ(m)                                  )l)  # If for all m in l
                 (andmap(λ(n)                   )l)     # If for all n in l
                             (not(memq(+ n m)l))        # n + m is not in l

3

05AB1E9 5字节

魔术八爪鱼缸节省了4个字节

ãOå_P

在线尝试!

说明

ã       # cartesian product
 O      # sum
  å     # check each if it exists in input
   _    # logical negation
    P   # product

05AB1E中的0真的是真的吗?
丹尼斯

@丹尼斯我将0定义为此挑战的真实性,将其他任何事物定义为虚假。只要它没有歧义并且OP没有指定特定格式,通常这还行吗?
Emigna '16

是我们对真实/虚假的默认解释。
丹尼斯

@丹尼斯:啊,太糟糕了。sum-free = 0和non-sum-free =“ a sum”非常适合挑战imo。看到了许多其他挑战,这些挑战将和和类似的非标准值定义为true / false,因此我认为明确性是默认设置。然后,我将编辑答案。感谢您的注意。
Emigna '16

1
@MagicOctopusUrn:谢谢!不确定这些命令当时是否能以这种方式工作,但是现在谢谢了:)(我也可能会错过它,当我完成这项挑战时,我对05AB1E还是很陌生)
Emigna

2

APL,8个字节

⊢≡⊢~∘.+⍨

说明:

⊢         argument
 ≡        equals
  ⊢       argument
   ~      without 
    ∘.+⍨  sums of its elements

测试:

      ( ⊢≡⊢~∘.+⍨ ) ¨ (1 5 7)(2 4 9 13)
1 0

2

Haskell,30个字节

f s=and[x+y/=z|x<-s,y<-s,z<-s]

我认为有一个更短的解决方案更有趣,但我还没有找到。

它们分别是33和34个字节:

f s=and$((/=)<$>s<*>)$(+)<$>s<*>s
f s|q<-((-)<$>s<*>)=all(/=0)$q$q$s

使用elem s并摆脱理解的最后一部分会如何?
Maltysen '16

@Maltysen如果你的意思是f s=and[notElem(x+y)s|x<-s,y<-s],这是32还有f s=all(`notElem`s)$(+)<$>s<*>s为31
同或

2

实际上,7个字节

;;∙♂Σ∩Y

在线尝试!

;;∙♂Σ∩Y              Stack: [1,5,7]
;         duplicate         [1,5,7] [1,5,7]
 ;        duplicate         [1,5,7] [1,5,7] [1,5,7]
  ∙       cartesian product [1,5,7] [[1,1],[1,5],[1,7],[5,1],[5,5],[5,7],[7,1],[7,5],[7,7]]
   ♂Σ     sum each          [1,5,7] [2,6,8,6,10,12,8,12,14]
     ∩    intersect         []
      Y   negate            1

也许使您的代码更加性别平等?(
暴民埃里克

1

TSQL,47个字节

CREATE table T(a int)
INSERT T values(1),(5),(7),(12)

SELECT min(iif(a.a+b.a<>T.a,1,0))FROM T a,T b,T

注意:此操作仅运行一次,然后需要删除或删除表才能再次运行。小提琴编辑器不允许创建表。因此,我的答案中包含的小提琴使用了2个额外的字节来弥补这一点-小提琴版本不需要清理。

小提琴


1

Perl,46个字节

45字节代码+ 1字节命令行(-p)

$_="$_ $_ $_"!~/(\b\d++.*)((?1))(??{$1+$2})/

使用单个正则表达式匹配项,并在Perl中支持正则表达式内的“代码表达式”,以便在匹配项中进行评估。

为了解决输入不排序的要求,我们将输入字符串重复三遍。这样可以保证结果在两个操作数之后,并允许再次匹配相同的数字(例如,在input的情况下2 4)。

用法示例:

echo "3 5 6 8" | perl -p entry.pl

1

因子,47字节

[ dup dup 2array [ Σ ] product-map ∩ { } = ]
  • ∩ { } =等于,但比短intersects?
  • Σ比短但等于sum

谢谢,math.unicode

测试代码:

USING: arrays kernel math.unicode sequences sequences.product ;
IN: sum-free

: sum-free? ( seq -- ? )
  dup dup 2array [ Σ ] product-map ∩ { } = ;

USING: tools.test sum-free ;
IN: sum-free.tests

{ t } [ { 5 7 9 } sum-free? ] unit-test
{ f } [ { 2 4 9 13 } sum-free? ] unit-test
{ t } [ { } sum-free? ] unit-test
{ f } [ { 0 } sum-free? ] unit-test
{ t } [ { 1 } sum-free? ] unit-test
{ f } [ { 0 1 } sum-free? ] unit-test

我只相信前两个是正确的。从这个问题尚不清楚其余部分应该是什么,所以我认为目前还可以。


1

PHP,73字节

+8将代码段转换为程序,过时的变量为-8,这要归功于insertusernamehere

<?foreach($argv as$p)foreach($argv as$q)if(in_array($p+$q,$argv))die;echo 1;

打印1true,空的输出false
使用:php <filename> <value1> <value2> ...

合格的测试功能(94 86):返回1或不返回

function f($a){foreach($a as$p)foreach($a as$q)if(in_array($p+$q,$a))return;return 1;}

测试

function out($a){if(!is_array($a))return$a;$r=[];foreach($a as$v)$r[]=out($v);return'['.join(',',$r).']';}
function cmp($a,$b){if(is_numeric($a)&&is_numeric($b))return 1e-2<abs($a-$b);if(is_array($a)&&is_array($b)&&count($a)==count($b)){foreach($a as $v){$w = array_shift($b);if(cmp($v,$w))return true;}return false;}return strcmp($a,$b);}
function test($x,$e,$y){static $h='<table border=1><tr><th>input</th><th>output</th><th>expected</th><th>ok?</th></tr>';echo"$h<tr><td>",out($x),'</td><td>',out($y),'</td><td>',out($e),'</td><td>',cmp($e,$y)?'N':'Y',"</td></tr>";$h='';}
$samples = [
    [], 1,
    [0], false,
    [1], 1,
    [0,1], false,
    [2, 4, 9, 13], false,
    [1,5,7], 1
];
while($samples)
{
    $a=array_shift($samples);
    $e=array_shift($samples);
    test($a,$e,f($a));
}

1
由于您从不使用$i,因此$j可以丢弃$i=>以及$j=>保存8个字节。不幸的是,代码片段不是有效的答案。使它成为一个函数或完整程序,并将其包括在字节数中,就可以开始使用了。:)
此处插入用户名,2016年

1

Java,67个字节

s->!s.stream().anyMatch(p->s.stream().anyMatch(q->s.contains(p+q)))

输入为Set<Integer>。测试:

import java.util.Arrays;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

public class SumFree {
    public static void main(String[] args) {
        sumFree(s->!s.stream()
            .anyMatch(p->s.stream()
                .anyMatch(q->s.contains(p+q)))); // formatted to avoid wrapping
    }

    public static void sumFree(Function<Set<Integer>, Boolean> func) {
        test(func);
        test(func, 4);
        test(func, 1, 5, 7);
        test(func, 16, 1, 4, 9);
        test(func, 1, 4, 5, 7);
        test(func, 0);
        test(func, 3, 0);
        test(func, 16, 1, 4, 8);
    }

    public static void test(Function<Set<Integer>, Boolean> func, Integer... vals) {
        Set<Integer> set = Arrays.stream(vals).collect(Collectors.toSet());
        System.out.format("%b %s%n", func.apply(set), set);
    }
}

输出:

true []
true [4]
true [1, 5, 7]
true [16, 1, 4, 9]
false [0]
false [1, 4, 5, 7]
false [0, 3]
false [16, 1, 4, 8]

1

Clojure,34个字节

#(not-any? %(for[i % j %](+ i j)))

我在注意到较早的Clojure解决方案之前写了这篇文章。无论如何,这是更紧凑的,因为它使用输入集作为的pred函数not-any?


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.