Nol jumlah mencakup

38

pengantar

Pertimbangkan daftar L kosong bilangan bulat. Sebuah zero-sum slice dari L adalah subsequence bersebelahan L yang jumlahnya sama dengan 0. Misalnya, [1, -3, 2] adalah zero-sum sepotong [-2, 4, 1, -3, 2, 2 , -1, -1] , tetapi [2, 2] tidak (karena itu tidak berjumlah 0), dan juga tidak [4, -3, -1] (karena tidak berdekatan).

Koleksi irisan zero-sum dari L adalah penutup zero-sum dari L jika setiap elemen milik setidaknya satu dari irisan. Sebagai contoh:

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

Tiga zero-sum irisan A , B dan C membentuk zero-sum sampul L . Beberapa salinan dari irisan yang sama dapat muncul dalam sampul zero-sum, seperti ini:

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

Tentu saja, tidak semua daftar memiliki sampul zero-sum; beberapa contoh adalah [2, -1] (setiap irisan memiliki jumlah bukan nol) dan [2, 2, -1, -1, 0, 1] ( 2 paling kiri bukan bagian dari irisan zero-sum).

Tugas

Input Anda adalah daftar bilangan bulat nonempty L , diambil dalam format apa pun yang masuk akal. Output Anda akan menjadi nilai kebenaran jika L memiliki penutup zero-sum, dan nilai palsu jika tidak.

Anda dapat menulis program atau fungsi lengkap, dan jumlah byte terendah menang.

Uji kasus

[-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
Zgarb
sumber
Dengan "setiap elemen milik salah satu irisan", apakah Anda memperlakukan nilai yang sama pada indeks yang berbeda sebagai berbeda?
ngenisis
@ngenisis Ya, mereka berbeda dan masing-masing harus muncul dalam irisan yang berisi indeks yang sesuai.
Zgarb
2
Tidakkah [2,2,-1,-1,0,1] -> Falseseharusnya contoh palsu ketiga menjadi benar karena kedua irisan [2,-1,-1]dan [-1,0,1]tambahkan ke nol dan semua elemen mereka ada di daftar asli?
dfernan
2 paling kiri bukan bagian dari zero-sum slice. Agak tidak jelas, tetapi mereka harus muncul di slice yang "berisi indeks mereka".
Zgarb
Dimengerti Itu membuatnya lebih sulit. : o)
dfernan

Jawaban:

11

Jelly , 13 12 byte

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

Cobalah online!

Bagaimana itu bekerja

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.
Dennis
sumber
9

Mathematica, 66 65 byte

Disimpan 1 byte, dan semoga belajar trik baru untuk masa depan, terima kasih kepada ngenisis!

Dua alternatif yang sama panjangnya, keduanya adalah fungsi yang tidak disebutkan namanya mengambil daftar bilangan bulat sebagai input dan mengembalikan Trueatau 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^#]}]&

Dalam kedua kasus, Tr@#[[i;;j]]hitung jumlah irisan input dari posisi ike posisi j(diindeks 1). Product[...,{i,k},{j,k,l}]mengalikan semua irisan-jumlah ini, sebagai irentang di atas indeks yang paling banyak kdan jrentang di atas indeks yang setidaknya k. (Perhatikan bahwa l=Tr[1^#]mendefinisikan lsebagai jumlah dari 1semua kekuatan dalam daftar input, yang hanya panjang dari daftar.) Dengan kata lain, produk ini sama dengan 0 jika dan hanya jika kelemen th milik kepingan zero-sum .

Dalam versi pertama, masing-masing produk tersebut dibandingkan dengan 0, dan And@@kembali Truetepat ketika setiap produk tunggal sama 0. Dalam versi kedua, daftar produk ditindaklanjuti oleh fungsi Norm(panjang lvektor -dimensi), yang sama dengan 0jika dan hanya jika setiap entri sama 0.

Greg Martin
sumber
1
Tr[1^#]menyimpan 1byte dari Length@#.
ngenisis
Apakah akan 0^berhasil 0==? Tidak yakin bagaimana Mathematica mengatasinya. (Anda akan kembali 1/ 0bukannya true/ false)
Cyoce
1
Ide keren, tetapi Mathematica kembali Indeterminateuntuk 0^0. Juga, 1/ 0tidak benar-benar truthy / falsy di Mathematica-itu terlalu kuat diketik untuk pegolf make happy :)
Greg Martin
7

Mathematica, 65 64 byte

Terima kasih kepada ngenisis karena telah menghemat 1 byte.

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

Saya lebih suka menemukan solusi pencocokan pola murni, tetapi terbukti rumit (dan hal-hal seperti {___,a__,___}selalu super panjang).

Martin Ender
sumber
4

Haskell, 94 byte

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

Contoh penggunaan: 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.

Cara kerjanya (mari gunakan [-1,1,5,-5]untuk input):

        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. 
nimi
sumber
powersliceadalah nama fungsi yang hebat.
Zgarb
3

Ruby, 81 byte

Cobalah online

Solusi brute force sederhana; untuk setiap elemen array, cobalah mencari irisan zero-sum yang berisi itu.

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

J, 36 35 byte

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

Untuk setiap subsum, saya menambahkan indeks elemen dan saya menyimpan indeks iff subsum 0dan kemudian memeriksa apakah setiap indeks ada.

Trik: indeks berbasis 1 daftar dapat dihasilkan dengan #\panjang mis. Setiap.

Pemakaian:

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

Cobalah online di sini.

randomra
sumber
Saya pikir Anda dapat menyimpan 2 byte menggunakan trik basis 1 untuk penjumlahan dan menggunakan perataan rata#\*/@e.&,]({:*0=1#.{.)@|:\.\@,.#\
mil
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)

Cuplikan tes

Produksi ETH
sumber
1

Python, 123 120 byte

-3 byte terima kasih kepada @Zgarb

Mempopulasikan daftar dengan ukuran yang sama dengan input dengan irisan zero-sum dan overwrites menurut indeks, mengembalikan kesetaraannya ke aslinya di akhir.

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
dfernan
sumber
1
Saya pikir Anda bisa menggunakan 0sebagai pengganti None. Tidak akan ada false positive, karena setiap 0input selalu merupakan bagian atau irisan zero-sum.
Zgarb
Kamu benar. Saya memikirkan hal itu tetapi akhirnya menyimpulkan bahwa hal itu dapat menimbulkan positif palsu.
dfernan
0

Scala, 49 byte

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

Cobalah di ideone

Pemakaian:

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

Tidak Disatukan:

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

Penjelasan:

% =>            //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
  )
corvus_192
sumber
Saya tidak begitu yakin bagaimana ini bekerja, tetapi saya pikir itu harus gagal pada beberapa kasus uji kebenaran.
Zgarb
@Zgarb Saya menambahkan tautan ke ideone, sehingga Anda dapat memverifikasi bahwa itu benar. Ini pada dasarnya kekuatan kasar, mencoba setiap irisan yang mungkin.
corvus_192
Anda dapat menggunakan %sebagai nama parameter? Keren!
Cyoce
@Cyoce Anda dapat menggunakan hampir semua char Unicode kecuali .,;:()[]{}\"'. Cukup berguna untuk bermain golf, karena mereka terpisah dari huruf oleh parse, sehingga Anda dapat menghemat spasi.
corvus_192
Saya memeriksa test case, dan sepertinya memberikan trueuntuk case falsy kedua.
Zgarb
0

Python, 86 Bytes

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 = Tidak ada

sonrad10
sumber
Ini salah mengembalikan 1untuk kasus uji ketiga.
Zgarb
1
Ini benar-benar kembali 1untuk semua kasus uji kecuali dua yang salah pertama.
dfernan
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))))

Menghasilkan semua partisi yang berjumlah nol, memeriksa bahwa ia memiliki indeks yang berbeda "panjang input vektor".

NikoNyrh
sumber
0

PHP, 104 byte

Brute force dan masih lebih dari 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;

mengambil input dari argumen baris perintah, 1untuk kebenaran, kosong untuk kepalsuan. Jalankan dengan -r.

kerusakan

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]berisi nama file; jika dijalankan dengan -r, itu akan -dan dievaluasi untuk 0untuk operasi numerik.

Titus
sumber
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)

Menghitung jumlah parsial untuk semua elemen i..jinklusif, dan me-reset unsur-unsur yang relevan dari bdari 1ke 0ketika menemukan sejumlah nol, akhirnya memeriksa bahwa tidak ada 1s kiri.

Neil
sumber