サインスワップ和


24

正の整数空でないリストが与えられた場合、あなたの仕事はの一意の値の数を決定することです± x ± y ± z ± (x,y,z,)±x±y±z±

たとえば、リスト 1、2、2)を考えます。合計を作成するには8つの方法があります。(1,2,2)

  • +1+2+2+5
  • +1+22+1
  • +12+2+1
  • +1223
  • 1+2+2+3
  • 1+221
  • 12+21
  • 1225

6つの一意の合計があるため、答えはです。6{5,5,1,1,3,3}6

テストケース

[1, 2] => 4
[1, 2, 2] => 6
[s]*n => n+1
[1, 2, 27] => 8
[1, 2, 3, 4, 5, 6, 7] => 29
[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] => 45
[1, 7, 2, 8, 3, 1, 6, 8, 10, 9] => 56
[93, 28, 92, 100, 43, 66, 2, 98, 2, 52, 57, 75, 39, 77, 45, 15, 13, 82, 81, 20, 68, 14, 5, 3, 72, 56, 57, 1, 23, 25, 76, 59, 60, 71, 71, 24, 1, 3, 72, 84, 72, 28, 83, 62, 66, 45, 21, 28, 49, 57, 70, 3, 44, 47, 1, 54, 53, 56, 36, 20, 99, 9, 89, 74, 1, 14, 68, 47, 99, 61, 46, 26, 69, 21, 20, 82, 23, 39, 50, 58, 24, 22, 48, 32, 30, 11, 11, 48, 90, 44, 47, 90, 61, 86, 72, 20, 56, 6, 55, 59] => 4728

参照ソリューション(サイズではなく速度を最適化します)。

ブルートフォース法などを使用しているために最後のケースを処理できない場合は、それで問題ありません。

得点

これはであるため、最短の有効なソリューション(バイト単位で測定)が優先されます。


入力が空の配列である場合を処理する必要がありますか?
チャスブラウン

@ChasBrownによると、入力は空ではありません。
ジョンファンミン

うーん、私は3番目のテストケースがどのように機能するか理解できません、説明してください?
エリックアウトゴルファー

@EriktheOutgolferそれのが効果的にあなたの配列はすべて同じ数字(例であれば言って[2,2,2,2,...])答えは、この場合、標識の位置は無関係と各事項の数だけあるので、+ 1これは、配列の長さでなければなりません
reffu

@reffuそれは冗談のようなもので、エラーによってそこに含まれているように見えます。
エリックアウトゴルファー

回答:


13

Wolfram言語(Mathematica)、27バイト

Tr[1^Fold[#⋃+##&,{0},#]]&

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

一意の符号交換合計の数を見つけることは、一意のサブセット合計の数を見つけることと同等です。

証明には、入力の合計を各符号交換合計に加算し、2で除算することが含まれます。次に、明らかな全単射があります。

説明

Fold[#⋃+##&,{0},#]

入力を繰り返し処理します。初期値は{0}<current value><current value> + input element(リストにマップ)の和集合を取ります。

Tr[1^ ... ]

Length関数のゴルフバージョン。


8

ゼリー、6バイト

ŒPS€QL

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

バックグラウンド

ましょLが入力リストとすること{P、N}正負と代数被加数にパーティション。チャレンジ仕様では s {P、N} = sum(P)-sum(N)を計算する必要があります。

ただし、sum(P)+ sum(N)= sum(L)およびsum(L)はパーティションに依存しないため、s {P、N} = sum(P)-sum(N)= sum( P)-(sum(L)-sum(P))= 2sum(P)-sum(L)

したがって、sum(P)の一意の各値は、s {P、N}一意の1つの値に対応します。

使い方

ŒPS€QL  Main link. Argument: A (array)

ŒP      Powerset; generate all subarrays of A.
  S€    Take the sum of each.
    Q   Unique; deduplicate the sums.
     L  Take the length.

7

MATL11 10バイト

nW:qBGY*un

オンラインでお試しください! これは、ルイスメンドーのOctave / MATLABの回答の移植版です。私はまだMATLを学ぼうとしていますが、MATLは今月の言語であるため、説明とともに投稿したいと思いました。

説明:

一般的なスタックベースのプログラミング、特にMATLに不慣れな方のための読み物です。

入力ベクトルは暗黙的にスタックに配置されます。スタック内の要素に対して操作が実行されると、その要素はスタックから削除されることに注意してください。

                % Stack:
                % [1, 2, 2]
n               % Counts the number of elements of the vector on the top of the stack.
                % Stack:
                % [3]
 W              % Raise 2^x, where x is the number above it in the stack
                % Stack:
                % [8]
  :             % Range from 1...x, where x is the number above it in the stack.                    % Stack:
                % [1, 2, 3, 4, 5, 6, 7, 8]
   q            % Decrement. Stack:
                % [0, 1, 2, 3, 4, 5, 6, 7]
    B           % Convert to binary. Stack:
                % [0,0,0; 0,0,1; 0,1,0; 0,1,1; 1,0,0; 1,0,1; 1,1,0; 1,1,1] 
     G          % Push input again. Stack:           
                % [0,0,0; 0,0,1; 0,1,0; 0,1,1; 1,0,0; 1,0,1; 1,1,0; 1,1,1], [1; 2; 2]
      Y*        % Matrix multiplication of the two elements on the stack.
                % Stack:
                % [0; 2; 2; 4; 1; 3; 3; 5]
        u       % Keep only unique elements. Stack:
                % [0; 2; 4; 1; 3; 5]
         n      % Number of elements in the vector. Stack:
                % [6]

そして、暗黙的にスタック上の最終要素を出力します。


1
いい説明!
ルイスメンドー


6

Python 2、52バイト

k=1
for n in input():k|=k<<n
print bin(k).count('1')

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

数値のバイナリ表現を使用して、到達可能なサブセットの合計を格納します。


1
これがどのように機能するか説明できますか?自分で思いついたのですか、それとも既知の結果ですか?
スンダ

1
@sundarそれほど複雑ではありません。この回答では、他の多くの回答と同様に、一意の合計(符号交換ではない)が計算されます。kの各ビットは合計に対応します。k<<n各合計にnを加算します。以前のすべてを保持kkながらこれらの新しい合計をストアで調整し、複製されたシムは記録されません
-H.PWiz

ああ、残骸の軌跡は、ジョンファンミンの全単射アイデアに戻ります。それは私が見逃していた主な洞察でした。ここで、各サブセットの合計は、ビットストリング内のその位置の1で表されます(LSBの最初の1は、空のサブセットの合計0を表します)。まだ「それほど複雑ではない」と呼ぶものではありませんが、それは私の経験の浅い話かもしれません。:)
スンダ


5

Haskell、46バイト

import Data.List
length.nub.map sum.mapM(:[0])

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

入力リストのサブセットを合計する代わりに、数値を保持するか、またはで置換するかのすべての組み合わせを作成します0。たとえば、

mapM(:[0])[1,2,3] -> [[1,2,3],[1,2,0],[1,0,3],[1,0,0],[0,2,3],[0,2,0],[0,0,3],[0,0,0]]

これは、より2バイト短いですsubsequences


いい答えだ!このようなものf x=sum[1|i<-[0..sum x],elem i$sum<$>mapM(:[0])x]がインポートよりも短いことを望みましたが、明らかにそうではありません。
リン

Mathematicaの1の翻訳よりもさらに短いニース、私はそれはきれいだと思うのが、:import Data.List;length.foldr((<*>)union.map.(+))[0]
ジョン・パーディ

5

R、83 75バイト

JayCeとGiuseppeのおかげで-8バイト

入力ベクトルのサイズに対して(1、-1)のすべての可能な組み合わせの行列を作成し、これを元のベクトルで乗算して合計を取得します。次に、一意で結果の長さを見つけます。

function(v)nrow(unique(t(t(expand.grid(rep(list(c(1,-1)),sum(v|1)))))%*%v))


前のバージョン:

f=function(v)nrow(unique(as.matrix(expand.grid(rep(list(c(1,-1)),length(v))))%*%v))

コメントなしでゴルフ:

f=function(vector){

  List=rep(list(c(1,-1)),length(vector))   ## Create a list with length(vector) elements, all (1,-1)

  Combinations=expand.grid(Length)    ## get all combinations of the elements of the list, e.g, 1,-1,1,1,-1,1

  Matrix=as.matrix(Combinations)   ## convert to matrix

  Results=Matrix%*%vector   ## multiply the matrix original vector to get a Nx1 matrix

  Unique_results=unique(Results)   ## unique the results

  nrow(Unique_results)   ## length = number of rows of unique values
  }

いくつかのバイトを保存tTIO
JayCe

そしてsum(v|1)、より短いバイトですlength(v)
ジュゼッペ





3

アタッシュ、29バイト

{#Unique[Flat!±_]}@Fold[`±]

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

これ±は、入力リスト上で演算子を折りたたみ、±そのリストを取得してから、配列の一意のアトムをカウントすることで機能します。

折りたたみの仕組みの例を次に示します。

Fold[`±][ [1,2] ] == 1 ± 2
                  == [1 + 2, 1 - 2]
                  == [3, -1]
Fold[`±][ [1,2,2] ] == (1 ± 2) ± 2
                    == [3, -1] ± 2
                    == [[3 + 2, 3 - 2], [-1 + 2, -1 - 2]]
                    == [[5, 1], [1, -3]]
                    == [5, 1, 1, -3]
Fold[`±][ [4,4,4,4] ] == (4 ± 4) ± 4 ± 4
                      == [8, 0] ± 4 ± 4
                      == [[12, 4], [4, -4]] ± 4
                      == [[[16, 8], [8, 0]], [[8, 0], [0, -8]]]
                      == [16, 8, 8, 0, 8, 0, 0, -8]
                      == [16, 8, 0, -8]

次に、PlusMinusをもう一度適用して、最終符号のすべての順列を生成します。

より効率的なバージョン、31バイト

`#@(q:=Unique@Flat@`±)@Fold[q]

オンラインでお試しください!これは、不必要な組み合わせを生成しないため、最終テストケースではタイムアウトしません。


3

R、62バイト

function(V)sum(unique(c(V%*%combn(rep(0:1,L),L<-sum(V|1))))|1)

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

ポートデニスのアルゴリズム。用語の包含/除外に同様のビットマップおよびマトリックス製品を使用するため、Octave / MATLの回答に最も近いです。







2

Bash + GNUユーティリティ、49バイト

eval echo "{,-}${@//,/{+,-\}}\;"|bc|sort -u|wc -l

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

コマンドラインでコンマ区切りリストとして指定された入力。

説明

               ${@//,/{+,-\}}                      # Replace commas with {+,-}
          "{,-}${@//,/{+,-\}}\;"                   # Build a brace expansion with {+,-} before every number and ; at the end
eval echo "{,-}${@//,/{+,-\}}\;"                   # Expand to give every combination expression, separated by ;
                                |bc                # Arithmetically evaluate each line
                                   |sort -u        # Remove duplicates
                                            wc -l  # Count

2

Linux用のx86_64マシン言語、31 29バイト

 0:   31 d2                   xor    %edx,%edx
 2:   6a 01                   pushq  $0x1
 4:   58                      pop    %rax
 5:   8b 0c 97                mov    (%rdi,%rdx,4),%ecx
 8:   48 89 c3                mov    %rax,%rbx
 b:   ff c2                   inc    %edx
 d:   48 d3 e3                shl    %cl,%rbx
10:   48 09 d8                or     %rbx,%rax
13:   39 d6                   cmp    %ese,%edx
15:   7c ee                   jle    5 <+0x5>
17:   f3 48 0f b8 c0          popcnt %rax,%rax
1c:   c3                      retq

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

@xnorの答えに触発されました。POPCNT命令を備えたマシンが必要です。




1

クリーン、82バイト

import StdEnv
f[]=length
f[h:t]=f t o foldr(\e l=removeDup[e+h,e-h:l])[]
?l=f l[0]

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

加算または減算後に可能な合計を削減するヘルパーとして? :: [Int] -> Int使用する関数を定義しますf :: [Int] -> ([Int] -> Int)


ここで「Haskellでは参照溶液のgolfedバージョンがね。どれだけCleanに持ち越せるかわかりませんが、そこから何かを引き出すことができるかもしれません。
エソランジングフルーツ

@EsolangingFruitありがとう。ただし、既に同じアプローチを使用しているため、参照ソリューションをゴルフで使用しても短縮する方法が見つかりません。
18年

1

APL(Dyalog Classic)、21バイト

⍴∘∪⊢+.×1-2×2(⍴⍨⊤∘⍳*)⍴

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

説明

2(⍴⍨⊤∘⍳*)⍴

に相当する関数{((⍴⍵)⍴2)⊤⍳(⍴⍵)}列。列としての入力の長さまでの0のバイナリ表現を持つ行列を生成します。

1-2×

1sを-1sに、0sを1sにマップ

⊢+.×

入力との行列乗算。すべての可能な合計の配列を提供します

⍴∘∪

重複を削除してからカウント


1

Java 8、207 83 44バイト

s->Long.bitCount(s.reduce(1L,(r,c)->r|r<<c))

@xnorのPython 2回答のポート。@Jakobの
おかげで-39バイト。

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

s->               // Method with Long-Stream parameter and long return-type
  Long.bitCount(  //  Return the amount of 1s in the binary representation of:
    s.reduce(1L,  //   Result-Long, starting at 1
     (r,c)->      //   Loop pair-wise (result,current):
      r|          //    Bitwise-OR the result `r` with:
        r<<c))    //    result `r` bitwise left-shifted by the current `c`

2
44バイトで十分です!次のストリームを取得Longs->Long.bitCount(s.reduce(1l,(a,e)->a|a<<e))
ヤコブ

@Jakobありがとう!私はいつも忘れます.reduce(そして.bitCount、追加するかもしれません。:)
ケビンクルーッセン

1
また、任意精度バージョンを作成しました。最も安価な方法は、セットではなくビットマップを使用することです。
ヤコブ

1

Java 8、85バイト

xnorの答えの別のJavaポート。元の答えと同様に、これは任意の精度のビットマップを使用するため、サブセット合計のサイズに上限はありません。

これは、シーケンシャルjava.util.stream.Stream<Integer>からのラムダintです。

s->s.reduce(java.math.BigInteger.ONE,(a,e)->a.or(a.shiftLeft(e)),(u,v)->u).bitCount()

オンラインで試す

reduceストリームはシーケンシャルであるため、コンバイナ(への3番目の引数)は使用されないことに注意してください。選択した機能は任意です。


1

ジュリア0.654の 52バイト

V->(~W=W==[]?0:∪([n=W[] -n].+~W[2:end]))(V)|>endof

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

(に置き換え¬て-2バイト、Jo King~に感謝

すべてのテストケースで機能します。ブロードキャストを使用してすべての可能な合計を収集し、それらをカウントします。

説明:

function g_(V)
  function inner(W)  #named ~ in golf version to save bytes
    W == [] ? 0 :    #return 0 when input empty (base case)
    ∪(               #unique elements of
      [n=W[] -n]     #take the first element and its negation
      .+             #broadcast-add that to each element of
      inner([2:end]) #sign-swapping sums of the rest of the array
     )
  end                #returns the list of unique elements out of those sums
  return endof(inner(V)) #return the length of that list
end

古いソリューション:

ジュリア0.6、64バイト

N->endof(∪([2(i&2^~-j>0)-1 for i=0:~-2^(l=endof(N)),j=1:l]*N))

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

63までの長さの入力配列で機能します(したがって、OPによると、最後のテストケースでは機能しません)。

説明:

function f_(N)
  endof(                            #length of
        ∪(                          #unique elements of
          [
           (i & 2^(j-1) > 0)        #check j'th bit (from right) of i
           * 2 - 1                  #convert bit value from (0,1)=>(-1,1)
           for i = 0:2^endof(N)-1,  #where i is numbers 0 to 2^length(N)-1
           j = 1:endof(N)           #and j is 1 to length(N) (i.e. the bits in i)
          ]                         #so we have a matrix [-1 -1 -1;1 -1 -1;1 -1 1;...]
          *                         #matrix multiply that with the input array, 
          N                         #thus calculating different combinations of 
         ))                         #sign-swapping sums
end

0

JavaScript(Babelノード)、64バイト

F=([f,...r],s=[0])=>f?F(r,s.flatMap(x=>[x+f,x])):new Set(s).size

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

これは最後のテストケースでは機能しません。


より効果的なソリューション(最後のテストケースで動作):

JavaScript(Babelノード)、71バイト

F=([f,...r],s=[0])=>f?F(r,[...new Set(s.flatMap(x=>[x+f,x]))]):s.length

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


これはのために実際のブラウザでは機能しませんArray#smoosh

バブラーのおかげで、[x+f,x-f]-> [x+f,x]は2バイトを節約します。


JungHwan Minによる証明)の[x+f,x]代わりに使用できます。[x+f,x-f]
バブラー

ES6バージョンでは+2バイト:F=([f,...r],s=[0])=>f?F(r,[...s,...s.map(x=>x+f)]):new Set(s).size
ニール

@Neil、そして... [...s,...s.map(x=>x+f)]s.concat(s.map(x=>x+f))と、s,s.map(x=>s.push(x+f))共有し、同じ長さ...
TSH

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