부호 교환 합계


24

비어 있지 않은 양의 정수 목록 주어지면 의 고유 값 수를 결정해야합니다.± x ± y ± z ± (엑스,와이,,)±엑스±와이±±

예를 들어 목록을 고려하십시오 . 합계를 만드는 8 가지 방법이 있습니다.(1,2,2)

  • +1+2+2+5
  • +1+22+1
  • +12+2+1
  • +122
  • 1+2+2+
  • 1+221
  • 12+21
  • 1225

6 개의 고유 한 합계 이 있으므로 답은 입니다.(6){5,5,1,1,,}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

참조 솔루션 (크기가 아닌 속도에 최적화)

무차별 대입 방법을 사용하여 마지막 사례를 처리 할 수 ​​없다면 괜찮습니다.

채점

이것은 이므로 가장 짧은 유효한 솔루션 (바이트 단위로 측정)이 이깁니다.


입력이 빈 배열 인 경우를 처리해야합니까?
Chas Brown

게시물에 따르면 @ChasBrown 입력이 비어 있지 않습니다.
JungHwan Min

흠, 세 번째 테스트 사례가 어떻게 작동하는지 이해할 수 없습니다. 설명해 주시겠습니까?
Outgolfer Erik

@EriktheOutgolfer 그것은 당신의 배열이 모두 같은 숫자라면 (예를 들어 [2,2,2,2,...]) 답은 배열의 길이 + 1이어야 함을 효과적으로 말하는 것 입니다.이 경우에 표시의 위치는 관련이없고 각 물질의
수만

@reffu 농담에 가깝습니다. 오류로 인해 포함 된 것처럼 보입니다.
Outgolfer Erik

답변:


13

Wolfram Language (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} 고유 값 하나에 해당합니다 .

작동 원리

Œ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

MATL , 11 10 바이트

nW:qBGY*un

온라인으로 사용해보십시오! 이것은 Luis Mendo의 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
좋은 설명입니다!
Luis Mendo


6

파이썬 2 , 52 바이트

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

온라인으로 사용해보십시오!

도달 가능한 부분 집합 합계를 저장하기 위해 숫자의 이진 표현을 사용합니다.


1
이것이 어떻게 작동하는지 설명해 주시겠습니까? 직접 생각해 보셨습니까, 아니면 알려진 결과입니까?
sundar-복원 모니카

1
@sundar 그렇게 복잡하지 않습니다. 이 답변은 다른 답변과 마찬가지로 고유 한 합계 (사인 교환이 아님)를 계산합니다. k의 각 비트는 합에 해당합니다. k<<n각 합계에 n을 더합니다. 이전의 모든 것을 유지하면서 중복 된 심들은 기록되지 kk
않고이

아, 간질의 흔적은 민환 민의 형용사로 되돌아 간다. 이것이 내가 놓친 주요 통찰이었다. 여기서 각 부분 집합 합계는 비트 열의 해당 위치에서 1로 표시됩니다 (LSB의 초기 1은 빈 부분 집합의 합계 0을 나타냄). 그래도 "복잡하지 않다"고 부르는 것은 아니지만 경험이 부족할 수도 있습니다. :)
sundar-복원 모니카


5

하스켈, 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]수입품보다 짧은 것이 좋기를 바랐 지만 그렇지 않은 것 같습니다.
Lynn

나는 그것이 더 예쁘다고 생각하지만 Mathematica 번역보다 훨씬 짧습니다.import Data.List;length.foldr((<*>)union.map.(+))[0]
Jon Purdy

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
  }

다음과 t같이 바이트를 절약하십시오 : TIO
JayCe

그리고 sum(v|1)바이트보다 짧습니다length(v)
Giuseppe





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의 참조 솔루션의 골프 버전은 다음과 같습니다 . Clean에 얼마나 많이 전달할 수 있는지 확실하지 않지만 무언가를 얻을 수 있습니다.
Esolanging Fruit

@EsolangingFruit 감사하지만 이미 동일한 접근 방식을 사용하고 있으며 참조 솔루션을 골프로 사용해도 단축 방법을 찾을 수 없습니다.
OUurous

1

APL (Dyalog Classic) , 21 바이트

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

온라인으로 사용해보십시오!

설명

2(⍴⍨⊤∘⍳*)⍴

{((⍴⍵)⍴2)⊤⍳(⍴⍵)}입력과 길이가 0 인 이진 표현을 갖는 행렬을 생성 하는와 동일한 함수 트레인

1-2×

지도 1s의 -1s와 0s의 1

⊢+.×

가능한 모든 합의 배열을 제공하는 입력과 행렬 곱셈

⍴∘∪

중복을 제거한 다음 계산


1

자바 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 바이트 만 있으면됩니다! Long: 의 스트림을 복용 s->Long.bitCount(s.reduce(1l,(a,e)->a|a<<e)).
Jakob

@Jakob 감사합니다! 나는 항상 잊어 버립니다 .reduce(그리고 .bitCount추가 할 수도 있습니다 ..>.>) -39 바이트! :)
Kevin Cruijssen

1
또한 방금 임의 정밀도 버전을 만들었습니다 . 가장 저렴한 방법은 여전히 ​​비트 세트가 아닌 비트 맵을 사용하는 것 같습니다.
Jakob

1

자바 8, 85 바이트

다른 Java 포트 xnor 의 답변에 대한. 원래 답변과 마찬가지로 임의 정밀도 비트 맵을 사용하므로 부분 집합 합의 크기에 대한 상한이 없습니다.

이 순차적에서 람다의 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스트림은 순차적이므로 결합기 (에 대한 세 번째 인수 )는 사용되지 않습니다. 내가 선택한 기능은 임의적입니다.


1

줄리아 0.6 , 54 52 바이트

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

온라인으로 사용해보십시오!

( Jo King 덕분에로 교체 ¬하여 -2 바이트~ )

모든 테스트 사례에서 작동합니다. 브로드 캐스트를 사용하여 가능한 모든 합계를 수집 한 다음 계산합니다.

설명:

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 (바벨 노드) , 64 바이트

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

온라인으로 사용해보십시오!

마지막 테스트 케이스에서는 작동하지 않습니다.


보다 효과적인 솔루션 (마지막 테스트 케이스에서 작동) :

자바 스크립트 (Babel Node) , 71 바이트

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

온라인으로 사용해보십시오!


이로 인해 실제 브라우저에서 작동하지 않습니다 Array#smoosh .

Bubbler 덕분에 [x+f,x-f]-> [x+f,x]는 2 바이트를 절약합니다.


( 정환 민의 증명)[x+f,x] 대신 사용할 수 있습니다 . [x+f,x-f]
Bubbler

ES6 버전의 경우 +2 바이트 :F=([f,...r],s=[0])=>f?F(r,[...s,...s.map(x=>x+f)]):new Set(s).size
Neil

@Neil, and ... [...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.