合計無料のセットですか?


32

セットは、一緒に追加されたときに2つの(必ずしも別個ではない)要素がセット自体の一部でない場合、合計がありません。

たとえば、{1, 5, 7}すべてのメンバーが奇数であり、合計2つの奇数が常に偶数であるため、合計は無料です。一方、セットのメンバーの{2, 4, 9, 13}いずれか2 + 2 = 4または合計として、合計はありません4 + 9 = 13

入力としてセットを受け取り、セットが和のない場合はTruthy値を出力し、そうでない場合は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 16

5
さらにいくつかのテストケースがいいかもしれません!
リン

4
ひどくテストケースが必要です。セットは完全に一意ですか?

3
あなたは、あなたが2つの合計がセットから必ずしも別個の要素ではないことを意味していることを明確にする必要があると思います。
グレゴリーニズベット

回答:


14

Pyth- 8 5バイト

3バイト節約してくれた@FryAmTheEggmanに感謝します。

!@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]を生成します。これらは2つの同じ要素であり、マップに表示されるべきではありません。
busukxuan 16

@busukxuan質問では、実際に重複を考慮するように求められます:2 + 2 = 4OPから。FryAmTheEggmanのゴルフの前の私の答えは、このために実際に.Cコンビネーションを交換で使用していました。
マルティセン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 16

16
アナグラムに賛成。
ニール

@feersumこれはあなたの質問です。
フィリップハグランド

@FilipHaglundいいえ、orlpです。
mbomb007

@ mbomb007深刻な場合、はい。しかし、それは重大な意味を持たない可能性があります。これはあなたの質問です/あなたは質問を所有しています/あなたはここで他の全員を打ち負かします(Python)彼らは「あなたOPです」とは言いませんでした。
エリックアウトゴルファー16

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 off、括弧/中括弧から大量のバイトを節約してくれてありがとう。また、関数が本来あるべき反対のブール値を返していたことを指摘してくれたニールにも感謝します。

再定義してバイト数を削減しようとしましたn.someが、残念ながらプロトタイプ関数であるため機能しません。Array.prototype.mapJSではより良い解決策があるかもしれませんが、いくつかの機能は本当に楽しいです。

.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)))
コナーオブライエン

1
問題ない!無名関数の動作のために機能します。ここで他のES6の回答を見てください。多くのことを学ぶでしょう:)
コナーオブライエン

1
こんにちは、PPCGへようこそ!
NoOneIsHere

1
この感覚は間違っています。集合に和がないかどうかを教えてくれます。また、n.contains(o+p)whichを使用すると、最も内側の2バイトを節約できますsome
ニール

1
申し訳ありませんが、はい、私は意図していましたincludes(元々は呼び出される予定でしたcontainsが、一部のライブラリーの定義が矛盾しています)。
ニール

12

MATL、5バイト

t&+m~

これは、すべてのエントリが真である場合は真実であり、1そうでない場合は偽である配列を出力します。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 16

@LLlAMnYPおかげで、式をコピーするとMathematicaが式を自動的にフォーマットするので、Unicode文字を手動で見つける必要がありました。間違ったものを見つけたに違いない。
シモンズ

1
@ASimmons Mathematicaで文字をハイライトしてF1を押すと、その特定の文字のヘルプページが表示され、常にその文字のUnicodeコードポイント(16進数)が含まれます。Unicodeとしてコピーするだけではいけないのは本当に面倒です。Mathematica.SEのどこかに「Unicodeとしてコピー」するための解決策があると思いますが、IIRCは決して簡単ではありませんでした。
マーティンエンダー

11

Haskell, 32, 30 bytes

簡単なソリューション:

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

Two bytes saved by @Lynn


f x=and[a+b/=c|a<-x,b<-x,c<-x] for 30 bytes.
Lynn


6

J, 18 10 8 bytes

8 bytes saved thanks to miles, and 2 thanks to FrownyFrog!

-:]-.+/~

Matches the original list with the set difference of tabulated sums. This is equivalent to:

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

for input y. This translates to:

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

+/~ returns a table of sums using y. For y =: 16 1 4 9, this gives:

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

Then, we use -., which produces a list consisting of all elements in y not in this table. If the list is sum-free, this will produce the same list. Then, -: checks for equality of lists, which produces the desired output.

Old, 18 bytes

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

+/~ creates a table of the values of the set added to itself, and e. checks if those members are in the original set. The rest of that is negating the maximal element.


-:]-.&,+/~ for 10 bytes using set difference -. and list matching -:
miles

Ooo, very nice!
Conor O'Brien

You don't need &, -. already works with cells of y.
FrownyFrog

@FrownyFrog Fascinating, TIL. Thanks!
Conor O'Brien

5

Retina, 45 44 bytes

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

Input is a decimal list of comma-separated numbers. Output is 0 (falsy) or 1 (truthy).

Try it online! (The first line enables a linefeed-separated test suite.)

Explanation

Stage 1: Substitution

\d+
<$&$*1>

This converts all elements of the input to unary and wraps them in <...>. The purpose of the angle brackets is to distinguish a list containing only 0 from an empty list (since the unary representation of 0 is empty itself).

Stage 2: Substitution

$
$`$`

We repeat the string 3 times by append it twice at the end.

Stage 3: Match

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

We now try to find three numbers in the result such that the first two add up to the third. Those matches are counted (this doesn't actually count all such tuples, because matches cannot overlap, but if such a tuple exists it will be found). Hence, we get 0 for sum-free sets and something positive otherwise.

Stage 4: Match

^0

Since the previous stage gave the opposite of what we want, we negate the result by counting the matches of ^0 which is 1 for input 0 and 0 for everything else.


5

Octave, 29 21 25 bytes

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

Thanks to Suever! It returns an array. I added 0 at the end to make [] become sum-free. To verify truthy and falsey in Octave, you can do this:

> 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

An alternative that returns 0 or 1 is:

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

You could change it to be @(s)~ismember(s+s',s) since arrays can be truthy/falsey
Suever

5

Clojure, 47 37 bytes

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

quite plain solution. uses list comprehension to find all elements which sum is equal to another element.

38 bytes variant:

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

1
Since in the challenge you are taking a set as your input, you can simply use the set to check for membership as in #(=(for[a % b % :when(%(+ a b))]a)[]) which can save 10 bytes
miles

@miles oh wow, thanks, i did kinda ignore that fact and worked with lists.
cliffroot

4

Perl 6,  24 21 20  19 bytes

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

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

Input is any Positional value like a List.
( a Set is an Associative so you would have to call .keys on it. )

Test:

#! /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 bytes

This shorter version benefitted from A Simmons' submission. No element needs to be removed from the list before IntegerPartitions is applied.

If an element cannot be partitioned into two integers (each from the list), then IntegerPartitions[#,{2},#]=={} holds. And checks whether this holds for every element in the list. If so, the list is sum-free.

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

Examples

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

False


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

True


There is a 2, but no odd numbers that differ by 2.

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

True


Do you have a defined somewhere else in your workbook? These expressions don't give the desired output when I evaluate them.
A Simmons

Thanks. That a should have been a #. I corrected it and removed a superfluous @.
DavidC

3

Ruby, 36 bytes

Constructs a cartesian product of the set against itself and finds the sum of all elements, then checks for intersection with the original set. Input is arrays, but in Ruby they have enough set operations to make it work out nicely anyways.

-1 byte over my original solution (used & instead of - and compared with []) because of inspiration from @feersum

Try it here!

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

3

Python, 40 bytes

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

^ = symmetric difference, new set with elements in either sets but not both

> True if the left set is a superset of the right set.


This doesn't work for the empty set, though I don't know if that's required.
xnor

1
Well, wikipedia says (among other things) that A is sum-free if the equation a + b = c has no solution with a, b, c ∈ A. With this definition, the empty set is not sum free, and my answer is correct. But I may be biased.
Lulhum

3
That definition implies that the empty set is sum-free, as there are no a, b and c in the empty set that satisfy the equation. The OP's newly added test cases support this.
Dennis

3

Brachylog, 13 bytes

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

Explanation

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

Is [2:2] a subset of 2 elements of [2:4:9]?
Leaky Nun

@LeakyNun No, because 2 only appears once in [2:4:9].
Fatalize

3

R, 39 36 bytes

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

Call as w(s), where s is the set (actually vector) of values. Here is the output for some test cases:

> 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

Where c() is the concatenation function that takes a bunch of values and makes it a vector.

EDIT: Making it an anonymous function to save 3 bytes, thanks to @MickyT.

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

Very nice. You can post these as an unnamed function if you like. That would save you 3 bytes. eg function(s)!any(outer(s,s,'+')%in%s)
MickyT

3

Racket, 58 bytes

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

Explanation:

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

05AB1E, 9 5 bytes

Saved 4 bytes thanks to Magic Octopus Urn

ãOå_P

Try it online!

Explanation

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

Is 0 really truthy in 05AB1E?
Dennis

@Dennis I defined 0 as truthy for this challenge and anything else as falsy. Isn't that normally OK as long as it is unambiguous and OP hasn't specified a specific format?
Emigna

This is our default interpretation of truthy/falsy.
Dennis

@Dennis: Ah, too bad. sum-free = 0 and non-sum-free = "a sum" fitted nicely to the challenge imo. Seen a lot of other challenges which defined sums and similar non-standard values as true/false so I figured un-ambiguity was the default. I'll edit the answer then. Thanks for the heads up.
Emigna

1
@MagicOctopusUrn: Thanks! Unsure if these commands worked this way back then, but they do now so thanks :) (I could just have missed it as well, I was pretty new to 05AB1E when I did this challenge)
Emigna

2

APL, 8 bytes

⊢≡⊢~∘.+⍨

Explanation:

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

Test:

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

2

Haskell, 30 bytes

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

I think there exists a shorter solution that's more interesting, but I haven't found it.

These are 33 and 34 bytes:

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

does using elem on s and getting rid of the last part of the comprehsion work?
Maltysen

@Maltysen If you mean f s=and[notElem(x+y)s|x<-s,y<-s], that's 32. There's also f s=all(`notElem`s)$(+)<$>s<*>s for 31.
xnor

2

Actually, 7 bytes

;;∙♂Σ∩Y

Try it online!

;;∙♂Σ∩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

Maybe make your code more gender-equal? ()
Erik the Outgolfer

1

TSQL, 47 bytes

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

Note: This will only run once, then the table needs to be deleted or dropped to run again. The fiddle editor doesn't allow creation of tables. Therefore the fiddle included in my answer uses 2 extra bytes to compensate for this - the fiddle version doesn't require cleanup.

Fiddle


1

Perl, 46 bytes

45 bytes code + 1 byte command line (-p)

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

Uses a single regex match with Perl's support for 'code expressions' inside the regex to allow for evaluation within a match.

To get around the requirement that the input is unsorted, we repeat the input string three times. This guarantees that the result is after the two operands, and allows the same digit to be matched again (e.g. in the case of input 2 4).

Usage example:

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

1

Factor, 47 bytes

[ dup dup 2array [ Σ ] product-map ∩ { } = ]
  • ∩ { } = is equivalent to but shorter than intersects?.
  • Σ is shorter than but equivalent to sum.

Thanks, math.unicode!

testing code:

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

I'm only confident the first two are correct. It's unclear from the question what the rest should be, so I think it's fine for now.


1

PHP, 73 bytes

+8 to turn the snippet into a program, -8 on obsolete variables thanks to insertusernamehere

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

prints 1 for true, empty output for false
usage: php <filename> <value1> <value2> ...

qualified function for testing (94 86): returns 1 or nothing

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

tests

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
As you never use $i and $j you can discard $i=> as well as $j=> and save 8 bytes. Unfortunately code snippets are not valid answers. Make it a function or a full program and include that in your byte count and you're ready to go. :)
insertusernamehere

1

Java, 67 bytes

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

Input is a Set<Integer>. Tests:

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

Output:

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 bytes

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

I wrote this before noticing the earlier Clojure solution. Anyway, this one is more compact as it uses the input set as a pred function for not-any?.


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