Không tổng bao gồm


38

Giới thiệu

Hãy xem xét một danh sách không trống L của các số nguyên. Một lát cắt có tổng bằng 0 của L là một chuỗi tiếp giáp của L có tổng bằng 0. Ví dụ: [1, -3, 2] là lát cắt tổng bằng 0 của [-2, 4, 1, -3, 2, 2 , -1, -1] , nhưng [2, 2] thì không (vì nó không bằng 0) và [4, -3, -1] (vì nó không liền kề nhau).

Một tập hợp các lát có tổng bằng 0 của Lvỏ bọc tổng bằng 0 của L nếu mọi phần tử thuộc về ít nhất một trong các lát. Ví dụ:

L = [-2, 4, 1, -3, 2, 2, -1, -1]
A = [-2, 4, 1, -3]
B =        [1, -3, 2]
C =                  [2, -1, -1]

Ba zero-sum lát Một , BC tạo thành một bìa zero-sum của L . Nhiều bản sao của cùng một lát có thể xuất hiện trong bìa có tổng bằng 0, như thế này:

L = [2, -1, -1, -1, 2, -1, -1]
A = [2, -1, -1]
B =        [-1, -1, 2]
C =                [2, -1, -1]

Tất nhiên, không phải tất cả các danh sách đều có bìa bằng 0; một số ví dụ là [2, -1] (mỗi lát cắt có tổng khác không) và [2, 2, -1, -1, 0, 1] ( 2 ngoài cùng bên trái không phải là một phần của lát cắt tổng bằng 0).

Nhiệm vụ

Đầu vào của bạn là một danh sách số nguyên không trống L , được lấy ở bất kỳ định dạng hợp lý nào. Đầu ra của bạn sẽ là một giá trị trung thực nếu L có vỏ bọc tổng bằng 0 và giá trị giả nếu không.

Bạn có thể viết một chương trình đầy đủ hoặc một hàm và số byte thấp nhất sẽ thắng.

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

[-1] -> False
[2,-1] -> False
[2,2,-1,-1,0,1] -> False
[2,-2,1,2,-2,-2,4] -> False
[3,-5,-2,0,-3,-2,-1,-2,0,-2] -> False
[-2,6,3,-3,-3,-3,1,2,2,-2,-5,1] -> False
[5,-8,2,-1,-7,-4,4,1,-8,2,-1,-3,-3,-3,5,1] -> False
[-8,-8,4,1,3,10,9,-11,4,4,10,-2,-3,4,-10,-3,-5,0,6,9,7,-5,-3,-3] -> False
[10,8,6,-4,-2,-10,1,1,-5,-11,-3,4,11,6,-3,-4,-3,-9,-11,-12,-4,7,-10,-4] -> False
[0] -> True
[4,-2,-2] -> True
[2,2,-3,1,-2,3,1] -> True
[5,-3,-1,-2,1,5,-4] -> True
[2,-1,-1,-1,2,-1,-1] -> True
[-2,4,1,-3,2,2,-1,-1] -> True
[-4,-1,-1,6,3,6,-5,1,-5,-4,5,3] -> True
[-11,8,-2,-6,2,-12,5,3,-7,4,-7,7,12,-1,-1,6,-7,-4,-5,-12,9,5,6,-3] -> True
[4,-9,12,12,-11,-11,9,-4,8,5,-10,-6,2,-9,10,-11,-9,-2,8,4,-11,7,12,-5] -> True

Bởi "mọi yếu tố thuộc về một trong các lát cắt", bạn có coi giá trị tương tự ở các chỉ số khác nhau là khác biệt không?
ngenisis

@ngenisis Có, chúng là khác biệt và mỗi cái sẽ xuất hiện trong một lát có chứa chỉ số tương ứng.
Zgarb

2
Không phải ví dụ [2,2,-1,-1,0,1] -> Falsegiả mạo thứ ba là sự thật vì cả hai lát [2,-1,-1][-1,0,1]thêm vào không và tất cả các yếu tố của chúng đều nằm trong danh sách ban đầu?
dfer Nam

2 ngoài cùng bên trái không phải là một phần của bất kỳ lát cắt tổng bằng không nào. Có một chút không rõ ràng, nhưng chúng phải xảy ra trong một lát "chứa chỉ mục của chúng".
Zgarb

Hiểu. Điều đó làm cho nó khó hơn. : o)
dfer Nam

Câu trả lời:


11

Thạch , 13 12 byte

JẆịS¥ÐḟċþJḄẠ

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

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

JẆịS¥ÐḟċþJḄẠ  Main link. Argument: A (array)

J             Yield all indices of A.
 Ẇ            Window; yield all slices of indices.
     Ðḟ       Filter; keep slices for which the link to the left returns 0.
    ¥           Combine the two atoms to the left into a dyadic chain.
  ị               Retrieve the elements of A at the slice's indices.
   S              Take the sum.
         J    Yield the indices of A.
       ċþ     Count table; count how many times each index appears in each table.
          Ḅ   Unbinary; convery the array of counts of each index from base 2 to 
              integer. This yields 0 iff an index does not appear in any slice.
           Ạ  All; return 1 iff all integers are non-zero.

9

Toán học, 66 65 byte

Đã lưu 1 byte và hy vọng học được một mẹo mới cho tương lai, nhờ ngenisis!

Hai lựa chọn thay thế dài bằng nhau, cả hai đều là các hàm không tên, lấy danh sách các số nguyên làm đầu vào và trả về Truehoặc False:

And@@Table[0==Product[Tr@#[[i;;j]],{i,k},{j,k,l}],{k,l=Tr[1^#]}]&

0==Norm@Table[Product[Tr@#[[i;;j]],{i,k},{j,k,l}],{k,l=Tr[1^#]}]&

Trong cả hai trường hợp, hãy Tr@#[[i;;j]]tính tổng của lát đầu vào từ vị trí này isang vị trí khác j(1 chỉ mục). Product[...,{i,k},{j,k,l}]bội số của tất cả các tổng số này, như icác phạm vi trên các chỉ số nhiều nhất kjphạm vi trên các chỉ số ít nhất k. (Lưu ý rằng l=Tr[1^#]định nghĩa llà tổng của 1tất cả các quyền hạn trong danh sách đầu vào, chỉ đơn giản là độ dài của danh sách.) Nói cách khác, sản phẩm này bằng 0 khi và chỉ khi kphần tử thứ đó thuộc về một lát có tổng bằng 0 .

Trong phiên bản đầu tiên, mỗi sản phẩm đó được so sánh 0And@@trả về Truechính xác khi mỗi sản phẩm đều bằng nhau 0. Trong phiên bản thứ hai, danh sách các sản phẩm được tác động bởi chức năng Norm(độ dài của lvectơ hai chiều), bằng với 0và chỉ khi mỗi mục nhập bằng nhau 0.


1
Tr[1^#]lưu 1byte từ Length@#.
ngenisis

Sẽ 0^làm việc thay vì 0==? Không chắc chắn làm thế nào Mathicala xử lý điều đó. (bạn sẽ trở lại 1/ 0thay vì true/ false)
Cyoce

1
Ý tưởng tuyệt vời, nhưng Mathicala trả lại Indeterminatecho 0^0. Ngoài ra, 1/ 0không thực sự là sự thật / giả dối trong Mathicala Học, nó được gõ quá mạnh để làm cho người chơi golf vui vẻ :)
Greg Martin

7

Toán học, 65 64 byte

Cảm ơn ngenisis vì đã tiết kiệm 1 byte.

Union@@Cases[Subsequences[x=Range@Tr[1^#]],a_/;Tr@#[[a]]==0]==x&

Tôi thà tìm một giải pháp khớp mẫu thuần túy, nhưng nó tỏ ra khó hiểu (và những thứ như {___,a__,___}luôn siêu dài).


4

Haskell, 94 byte

import Data.Lists
g x=(1<$x)==(1<$nub(id=<<[i|(i,0)<-fmap sum.unzip<$>powerslice(zip[1..]x)]))

Ví dụ sử dụng: g [-11,8,-2,-6,2,-12,5,3,-7,4,-7,7,12,-1,-1,6,-7,-4,-5,-12,9,5,6,-3] -> True.

Cách thức hoạt động (hãy sử dụng [-1,1,5,-5]cho đầu vào):

        zip[1..]x  -- zip each element with its index
                   -- -> [(1,-1),(2,1),(3,5),(4,-5)]
      powerslice   -- make a list of all continuous subsequences
                   -- -> [[],[(1,-1)],[(1,-1),(2,1)],[(1,-1),(2,1),(3,5)],[(1,-1),(2,1),(3,5),(4,-5)],[(2,1)],[(2,1),(3,5)],[(2,1),(3,5),(4,-5)],[(3,5)],[(3,5),(4,-5)],[(4,-5)]]
    <$>            -- for each subsequence
   unzip           --   turn the list of pairs into a pair of lists
                   --   -> [([],[]),([1],[-1]),([1,2],[-1,1]),([1,2,3],[-1,1,5]),([1,2,3,4],[-1,1,5,-5]),([2],[1]),([2,3],[1,5]),([2,3,4],[1,5,-5]),([3],[5]),([3,4],[5,-5]),([4],[-5])]
  fmap sum         --   and sum the second element
                   --   -> [([],0),([1],-1),([1,2],0),([1,2,3],5),([1,2,3,4],0),([2],1),([2,3],6),([2,3,4],1),([3],5),([3,4],0),([4],-5)]
 [i|(i,0)<-    ]   -- take all list of indices where the corresponding sum == 0
                   -- -> [[],[1,2],[1,2,3,4],[3,4]]
 id=<<             -- flatten the list
                   -- -> [1,2,1,2,3,4,3,4]
nub                -- remove duplicates
                   -- -> [1,2,3,4]

(1<$x)==(1<$    )  -- check if the above list has the same length as the input list. 

powerslicelà một tên chức năng tuyệt vời như vậy.
Zgarb

3

Ruby, 81 byte

Dùng thử trực tuyến

Giải pháp vũ phu đơn giản; đối với mọi phần tử của mảng, hãy thử tìm một lát có tổng bằng 0 có chứa nó.

->a{(0..l=a.size).all?{|i|(0..i).any?{|j|(i..l).any?{|k|a[j..k].inject(:+)==0}}}}

3

J, 36 35 byte

#\*/@e.[:;]({:*0=[:+/{.)@|:\.\@,.#\

Đối với mỗi tiểu mục, tôi thêm các chỉ mục của phần tử và tôi giữ các chỉ mục đó là phần phụ 0và sau đó kiểm tra xem mọi chỉ mục có hiện diện không.

Thủ thuật: Các chỉ mục dựa trên 1 của danh sách có thể được tạo với #\độ dài của mỗi tiền tố.

Sử dụng:

   (#\*/@e.[:;]({:*0=[:+/{.)@|:\.\@,.#\) 2 _1 _1 2
1
   (#\*/@e.[:;]({:*0=[:+/{.)@|:\.\@,.#\) 2 _1
0

Hãy thử trực tuyến tại đây.


Tôi nghĩ rằng bạn có thể tiết kiệm 2 byte bằng cách sử dụng thủ thuật cơ sở 1 cho tổng và sử dụng một flatten gồm#\*/@e.&,]({:*0=1#.{.)@|:\.\@,.#\
dặm

2

JavaScript (ES6), 109 byte

f=([q,...a],b=[],c=[])=>1/q?f(a,[...b,0].map((x,i)=>x+q||(c=c.map((n,j)=>n|i<=j)),c.push(0)),c):c.every(x=>x)

Kiểm tra đoạn


1

Python, 123 120 byte

-3 byte nhờ @Zgarb

Dân số một danh sách có cùng kích thước với đầu vào với các lát bằng 0 và ghi đè theo chỉ mục, trả lại giá trị bằng của nó về ban đầu ở cuối.

def f(l):
 s=len(l);n=[0]*s
 for i in range(s):
  for j in range(i,s+1):
   if sum(l[i:j])==0:n[i:j]=l[i:j]
 return n==l

1
Tôi nghĩ bạn có thể sử dụng 0như giữ chỗ thay vì None. Sẽ không có dương tính giả, bởi vì mọi 0đầu vào luôn là một phần hoặc một lát cắt tổng bằng không.
Zgarb

Bạn đúng rồi. Tôi đã nghĩ về điều đó nhưng cuối cùng kết luận rằng nó có thể phát sinh trong các kết quả dương tính giả.
dfer Nam

0

Scala, 49 byte

% =>(1 to%.size)flatMap(%sliding)exists(_.sum==0)

Hãy thử nó tại ideone

Sử dụng:

val f:(Seq[Int]=>Boolean)= % =>(1 to%.size)flatMap(%sliding)exists(_.sum==0)
f(Seq(4, -2, -2)) //returns true

Ung dung:

array=>(1 to array.size)
  .flatMap(n => array.sliding(n))
  .exists(slice => slice.sum == 0)

Giải trình:

% =>            //define a anonymouns function with a parameter called %
  (1 to %.size) //create a range from 1 to the size of %
  flatMap(      //flatMap each number n of the range
    %sliding    //to an iterator with all slices of % with length n
  )exists(      //check whether there's an iterator with a sum of 0
    _.sum==0
  )

Tôi không chắc chắn chính xác làm thế nào điều này hoạt động, nhưng tôi nghĩ rằng nó sẽ thất bại trong một số trường hợp thử nghiệm trung thực.
Zgarb

@Zgarb Tôi đã thêm một liên kết đến ideone, vì vậy bạn có thể xác minh rằng nó đúng. Về cơ bản, nó là một kẻ vũ phu, cố gắng mọi lát cắt có thể.
corvus_192

Bạn có thể sử dụng %như một tên tham số? Mát mẻ!
Cyoce

@Cyoce Bạn có thể sử dụng khá nhiều char Unicode ngoại trừ .,;:()[]{}\"'. Khá hữu ích cho việc chơi gôn, bởi vì chúng được phân tách từ các chữ cái bởi phân tích cú pháp, vì vậy bạn có thể lưu một số khoảng trắng.
corvus_192

Tôi đã kiểm tra các trường hợp thử nghiệm, và nó dường như đưa ra truecho trường hợp giả thứ hai.
Zgarb

0

Python, 86 byte

def f(l):
 r=range(len(l))
 if[i for i in r for j in r if sum(l[j:j+i+1])==0]:return 1

Truthy = 1 Falsy = Không


Điều này trả về không chính xác 1cho trường hợp thử nghiệm thứ ba.
Zgarb

1
Nó thực sự trả về 1cho tất cả các trường hợp thử nghiệm ngoại trừ hai trường hợp giả mạo đầu tiên.
dfer Nam

0

Clojure, 109 byte

#(=(count %)(count(set(flatten(for[r[(range(count %))]l r p(partition l 1 r):when(=(apply +(map % p))0)]p))))

Tạo tất cả các phân vùng có tổng bằng 0, kiểm tra xem nó có các chỉ số riêng biệt "chiều dài của vectơ đầu vào" không.


0

PHP, 104 byte

Lực lượng vũ phu và vẫn còn hơn 99 byte. :-(

for($p=$r=$c=$argc;$s=--$p;)for($i=$c;$s&&$k=--$i;)for($s=0;$k<$c&&($r-=!$s+=$argv[$k++])&&$s;);echo!$r;

lấy đầu vào từ các đối số dòng lệnh, 1cho sự thật, trống cho giả. Chạy với -r.

phá vỡ

for($p=$r=$argc;$s=$p--;)   # loop $p from $argc-1 to 0 with dummy value >0 for $s
    for($i=$p;$s&&$k=$i--;)     # loop $i (slice start) from $p to 1, break if sum is 0
        for($s=0;                   # init sum to 0
            $k<$argc                # loop $k (slice end) from $i to $argc-1
            &&($r-=!$s+=$argv[$k++])    # update sum, decrement $r if sum is 0
            &&$s;);                     # break loop if sum is 0
echo!$r;                    # $r = number of elements that are not part of a zero-sum slice

$argv[0]chứa tên tệp; nếu chạy với -r, nó sẽ được -và đánh giá 0cho các ops số.


0

JavaScript (ES6), 102 byte

a=>(g=f=>a.map((_,i)=>f(i)))(i=>g(j=>j<i||(t+=a[j])||g(k=>b[k]&=k<i|k>j),t=0),b=g(_=>1))&&!/1/.test(b)

Tính tổng một phần cho tất cả các phần tử đã i..jbao gồm và đặt lại các phần tử có liên quan btừ 1đến 0khi tìm thấy tổng bằng 0, cuối cùng kiểm tra xem có 1còn lại s không .

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.