Ký tổng hoán đổi


24

Đưa ra một danh sách không có số nguyên dương , công việc của bạn là xác định số lượng giá trị duy nhất của(x,y,z,Giáo dục)±x±y±z±Giáo dục

Ví dụ, hãy xem xét danh sách . Có tám cách có thể để tạo ra một khoản tiền:(1,2,2)

  • +1+2+2+5
  • +1+2-2+1
  • +1-2+2+1
  • +1-2-2-3
  • -1+2+2+3
  • -1+2-2-1
  • -1-2+2-1
  • -1-2-2-5

Có sáu khoản tiền duy nhất , vì vậy câu trả lời là .6{5,-5,1,-1,3,-3}6

Các trường hợp thử nghiệm

[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

Giải pháp tham khảo (tối ưu hóa cho tốc độ và không kích thước).

Nếu bạn không thể xử lý trường hợp cuối cùng vì bạn sử dụng phương pháp vũ phu hoặc tương tự, thì tốt thôi.

Chấm điểm

Đây là , vì vậy giải pháp hợp lệ ngắn nhất (tính bằng byte) sẽ thắng.


Chúng ta có phải xử lý trường hợp đầu vào là mảng trống không?
Chas Brown

@ChasBrown đầu vào không trống, theo bài viết.
JungHwan Min

Hừm, tôi không thể hiểu trường hợp thử nghiệm thứ ba hoạt động như thế nào, quan tâm giải thích thế nào?
Erik the Outgolfer

@EriktheOutgolfer Nó có hiệu quả nói nếu mảng của bạn là tất cả các số giống hệt nhau (ví dụ [2,2,2,2,...]) câu trả lời nên là chiều dài của mảng + 1. Điều này là do trong trường hợp này vị trí của các dấu hiệu là không thích hợp và chỉ số của từng vấn đề
reffu

@reffu Đó là một trò đùa nhiều hơn, có vẻ như nó đã được đưa vào đó bởi lỗi.
Erik the Outgolfer

Câu trả lời:


13

Ngôn ngữ Wolfram (Mathicala) , 27 byte

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

Hãy thử trực tuyến!

Tìm số lượng tổng hoán đổi ký hiệu duy nhất tương đương với việc tìm số lượng tổng phụ duy nhất.

Một bằng chứng sẽ liên quan đến việc thêm tổng của đầu vào cho mỗi khoản tiền hoán đổi ký hiệu và chia cho hai. Sau đó, có một sự lựa chọn rõ ràng.

Giải trình

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

Lặp lại thông qua đầu vào, với giá trị ban đầu là {0}: lấy liên kết giữa <current value><current value> + input element(ánh xạ vào danh sách).

Tr[1^ ... ]

Phiên bản golf của Lengthchức năng.


8

Thạch , 6 byte

ŒPS€QL

Hãy thử trực tuyến!

Lý lịch

Đặt L là danh sách đầu vào và {P, N} một phân vùng thành các đại số đại số với các dấu hiệu tích cực và tiêu cực. Thông số thử thách yêu cầu tính s {P, N} = sum (P) - sum (N) .

Tuy nhiên, vì sum (P) + sum (N) = sum (L)sum (L) không phụ thuộc vào phân vùng, nên chúng tôi có s {P, N} = sum (P) - sum (N) = sum ( P) - (tổng (L) - tổng (P)) = 2sum (P) - tổng (L) .

Do đó, mỗi giá trị duy nhất của tổng (P) tương ứng với một giá trị duy nhất của s {P, N} .

Làm thế nào nó hoạt động

Œ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 byte

nW:qBGY*un

Hãy thử trực tuyến! Đây là một câu trả lời Octave / MATLAB của Luis Mendo . Tôi vẫn đang cố gắng học MATL và tôi nghĩ rằng tôi sẽ đăng nó cùng với một lời giải thích, vì MATL là ngôn ngữ của tháng.

Giải trình:

Đây là phần đọc cho bất kỳ ai không quen thuộc với lập trình dựa trên ngăn xếp nói chung và MATL nói riêng.

Vectơ đầu vào được đặt ngầm trên ngăn xếp. Lưu ý rằng khi một thao tác được thực hiện trên một phần tử trong ngăn xếp, thì phần tử đó sẽ bị xóa khỏi ngăn xếp.

                % 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]

Và sau đó nó xuất ra phần tử cuối cùng trên ngăn xếp.


1
Giải thích tốt đẹp!
Luis Mendo


6

Python 2 , 52 byte

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

Hãy thử trực tuyến!

Sử dụng biểu diễn nhị phân của một số để lưu trữ các tập hợp con có thể tiếp cận.


1
Bạn có thể giải thích làm thế nào điều này hoạt động? Bạn đã tự mình nghĩ ra nó, hay nó là một kết quả được biết đến?
- Phục hồi Monica

1
@sundar Nó không phức tạp lắm. Câu trả lời này tính toán các khoản tiền duy nhất (không phải hoán đổi ký hiệu) như nhiều câu trả lời khác. Mỗi bit trong k tương ứng với một tổng. k<<nthêm n vào mỗi tổng. Oring với kcác cửa hàng số tiền mới này trong kkhi giữ tất cả những cái trước đó và Sim trùng lặp không được ghi lại
H.PWiz

À, dấu vết của sự vi phạm dẫn trở lại ý tưởng về sự quyến rũ của JungHwan Min , đó là cái nhìn sâu sắc chính mà tôi đã bỏ lỡ. Ở đây, mỗi tổng tập hợp con được biểu thị bằng 1 ở vị trí đó trong chuỗi bit (với 1 ban đầu trong LSB đại diện cho tổng 0 cho tập hợp con trống). Vẫn không có gì tôi gọi là "không phức tạp", nhưng đó có thể chỉ là sự thiếu kinh nghiệm của tôi. :)
- Phục hồi Monica


5

Haskell, 46 byte

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

Hãy thử trực tuyến!

Thay vì tổng hợp các tập hợp con của danh sách đầu vào, chúng tôi thực hiện tất cả các kết hợp hoặc giữ một số hoặc thay thế nó bằng 0, ví dụ:

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]]

Đây là hai byte ngắn hơn subsequences.


Câu trả lời tốt đẹp! Tôi hy vọng một cái gì đó như f x=sum[1|i<-[0..sum x],elem i$sum<$>mapM(:[0])x]sẽ ngắn hơn nhập khẩu, nhưng rõ ràng, nó không phải là.
Lynn

Đẹp, thậm chí còn ngắn hơn bản dịch của Mathicala, mặc dù tôi nghĩ nó đẹp hơn:import Data.List;length.foldr((<*>)union.map.(+))[0]
Jon Purdy

5

R, 83 75 byte

-8 byte nhờ JayCe và Giuseppe

Tạo một ma trận gồm tất cả các kết hợp có thể có (1, -1) cho kích thước của vectơ đầu vào, nhân số này với vectơ gốc để lấy tổng. Sau đó, duy nhất và tìm độ dài của kết quả.

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


phiên bản trước:

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

Ungolfed với ý kiến:

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
  }

Lưu một số byte với t: TIO
JayCe

sum(v|1)là một byte ngắn hơnlength(v)
Giuseppe

4

Octave / MATLAB, 45 41 40 byte

@(x)nnz(unique(dec2bin(0:2^nnz(x)-1)*x))

Đầu vào là một vectơ cột (sử dụng ;như dấu phân cách).

Các lỗi mã cho trường hợp thử nghiệm cuối cùng do hạn chế bộ nhớ.

Điều này sử dụng một ý tưởng từ câu trả lời của JungHwan Min (tập hợp con thay vì dấu hiệu xen kẽ) để lưu một vài byte.

Hãy thử trực tuyến!





3

Tùy viên , 29 byte

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

Hãy thử trực tuyến!

Điều này hoạt động bằng cách gấp ±toán tử trên danh sách đầu vào, sau đó lấy ±danh sách đó, sau đó đếm các nguyên tử duy nhất của mảng.

Dưới đây là một số ví dụ về cách hoạt động của nếp gấp:

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]

Sau đó, chúng tôi tạo ra tất cả các hoán vị của dấu hiệu cuối cùng bằng cách áp dụng PlusMinus một lần nữa.

Phiên bản hiệu quả hơn, 31 byte

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

Hãy thử trực tuyến! Điều này không hết thời gian trong trường hợp thử nghiệm cuối cùng, vì nó không tạo ra các kết hợp không cần thiết.


3

R , 62 byte

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

Hãy thử trực tuyến!

Thuật toán của cổng Dennis. Nó gần nhất với các câu trả lời Octave / MATL vì nó sử dụng một sản phẩm ma trận và bitmap tương tự để đưa vào / loại trừ các thuật ngữ.







2

Tiện ích Bash + GNU, 49 byte

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

Hãy thử trực tuyến!

Đầu vào được đưa ra dưới dạng danh sách được phân tách bằng dấu phẩy tại dòng lệnh.

Giải trình

               ${@//,/{+,-\}}                      # 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

x86_64 ngôn ngữ máy cho Linux, 31 29 byte

 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

Hãy thử trực tuyến!

Lấy cảm hứng từ câu trả lời của @ xnor. Yêu cầu một máy có POPCNThướng dẫn.




1

Sạch , 82 byte

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

Hãy thử trực tuyến!

Xác định hàm ? :: [Int] -> Intsử dụng f :: [Int] -> ([Int] -> Int)như một trình trợ giúp để giảm trên mỗi tổng có thể sau khi cộng hoặc trừ.


Đây là phiên bản đánh gôn của giải pháp tham chiếu trong Haskell; không chắc chắn nó có thể mang theo bao nhiêu đến Clean nhưng bạn có thể lấy được thứ gì đó từ nó.
Trái cây Esolanging

@EsolangingFnut Cảm ơn, nhưng nó đã sử dụng cùng một cách tiếp cận và tôi không thể tìm ra cách rút ngắn nó ngay cả với giải pháp tham chiếu được đánh gôn.
urur

1

APL (Dyalog Classic) , 21 byte

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

Hãy thử trực tuyến!

Giải trình

2(⍴⍨⊤∘⍳*)⍴

Một hàm đào tạo tương đương với {((⍴⍵)⍴2)⊤⍳(⍴⍵)}, tạo ra một ma trận có các biểu diễn nhị phân từ 0 đến độ dài của đầu vào dưới dạng các cột

1-2×

Bản đồ 1s đến -1s và 0s đến 1s

⊢+.×

Phép nhân ma trận với đầu vào, cung cấp một mảng của tất cả các khoản tiền có thể

⍴∘∪

Xóa các bản sao, sau đó đếm


1

Java 8, 207 83 44 byte

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

Cổng câu trả lời Python 2 của @ xnor .
-39 byte nhờ @Jakob .

Hãy thử trực tuyến .

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 byte là tất cả chúng ta cần! Lấy một dòng của Long: s->Long.bitCount(s.reduce(1l,(a,e)->a|a<<e)).
Jakob

@Jakob Cảm ơn! Tôi luôn quên về .reduce(và .bitCountcũng có thể tôi sẽ thêm ..>.>) -39 byte ngay tại đó! :)
Kevin Cruijssen

1
Ngoài ra tôi chỉ thực hiện một phiên bản chính xác tùy ý . Có vẻ như cách rẻ nhất để làm điều đó vẫn là với một bitmap chứ không phải là các bộ.
Jakob

1

Java 8, 85 byte

Một cổng Java khác của câu trả lời của xnor . Giống như câu trả lời ban đầu, điều này sử dụng một bitmap có độ chính xác tùy ý để không có giới hạn trên đối với kích thước của một tập hợp con.

Đó là một lambda từ một chuỗi java.util.stream.Stream<Integer> đến int.

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

Dùng thử trực tuyến

Lưu ý rằng bộ kết hợp (đối số thứ ba đến reduce) không được sử dụng do luồng là tuần tự. Hàm tôi chọn là tùy ý.


1

Julia 0,6 , 54 52 byte

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

Hãy thử trực tuyến!

( -2 byte bằng cách thay thế ¬bằng ~, nhờ Jo King )

Hoạt động cho tất cả các trường hợp thử nghiệm. Làm cho việc sử dụng phát sóng để thu thập tất cả các khoản tiền có thể, sau đó đếm chúng.

Giải trình:

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

Giải pháp cũ hơn:

Julia 0,6 , 64 byte

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

Hãy thử trực tuyến!

Hoạt động cho các mảng đầu vào có độ dài lên tới 63 (vì vậy không hoạt động cho trường hợp thử nghiệm cuối cùng, điều này cũng ổn theo OP).

Giải trình:

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 (Nút Babel) , 64 byte

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

Hãy thử trực tuyến!

Điều này sẽ không làm việc cho testcase cuối cùng.


Giải pháp hiệu quả hơn (hoạt động trên testcase cuối cùng):

JavaScript (Nút Babel) , 71 byte

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

Hãy thử trực tuyến!


Điều này sẽ không hoạt động trong một trình duyệt thực sự do Array#smoosh.

Nhờ Bubbler, [x+f,x-f]-> [x+f,x]tiết kiệm 2 byte.


Bạn có thể sử dụng [x+f,x]thay thế [x+f,x-f]( bằng chứng của JungHwan Min ).
Bong bóng

+2 byte cho phiên bản ES6:F=([f,...r],s=[0])=>f?F(r,[...s,...s.map(x=>x+f)]):new Set(s).size
Neil

@Neil, và ... [...s,...s.map(x=>x+f)],, s.concat(s.map(x=>x+f))và, s,s.map(x=>s.push(x+f))chia sẻ cùng một chiều dài ...
tsh

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.