零和保障


38

介绍

考虑一个非空整数列表L。零和切片大号是的连续子序列大号其总和等于0。例如,[1,-3,2]是零和切片[-2,4,1,-3,2,2 ,-1,-1],但[2,2]不是(因为它的总和不为0),[4,-3,-1]也不是(因为它不连续)。

的零和切片的集合大号零和盖大号如果每一个元素属于切片中的至少一个。例如:

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

三个零和切片ABC构成L的零和覆盖。同一切片的多个副本可以出现在零和封面中,如下所示:

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

当然,并非所有列表都具有零和保险;例如[2,-1](每个切片的总和都不为零)和[2,2,-1,-1,-1,0,1](最左边的2不是零和切片的一部分)。

任务

您的输入是采用任何合理格式的非空整数列表L。如果L的总和为零,则输出为真实值,否则为假值。

您可以编写完整的程序或函数,最低的字节数为准。

测试用例

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

通过“每个元素属于切片之一”,您是否将不同索引处的相同值视为不同?
ngenisis

@ngenisis是的,它们是不同的,每个都应出现在包含相应索引的切片中。
Zgarb

2
第三个虚假的例子不应该[2,2,-1,-1,0,1] -> False是真实的,因为两个slice [2,-1,-1]和都[-1,0,1]加零并且它们的所有元素都在原始列表中?
dfernan '17

最左边的2不属于任何零和切片。尚不清楚,但是它们必须出现在“包含其索引”的切片中。
Zgarb

明白了 这使它更加困难。:o)
dfernan

Answers:


11

果冻13 12字节

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

在线尝试!

这个怎么运作

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

Mathematica,66 65字节

感谢ngenisis,节省了1个字节,并希望为将来学到新的技巧!

两个等长的替代方案,它们都是未命名函数,将整数列表作为输入并返回Trueor 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^#]}]&

在这两种情况下,都Tr@#[[i;;j]]计算从位置i到位置j(1索引)的输入切片的总和。Product[...,{i,k},{j,k,l}]将所有这些slice-sum的整数倍相乘,i即最大索引范围内kj至少索引范围内k。(请注意,它l=Tr[1^#]定义l1输入列表中所有幂的总和,仅是列表的长度。)换句话说,当且仅当k第一个元素属于零和切片时,此乘积等于0。。

在第一个版本中,将每个产品与进行比较0,并在每个产品等于时精确And@@返回。在第二个版本中,乘积(维向量的长度)作用于产品列表,该函数在且仅当每个条目都等于时才等于。True0Norml00


1
Tr[1^#]保存中的1字节Length@#
ngenisis

0^代替0==吗?不确定Mathematica是如何处理的。(您将返回1/ 0而不是true/ false
Cyoce

1
很酷的想法,但数学的回报Indeterminate0^0。另外,1/ 0在Mathematica中实际上不是真实的/虚假的-输入的类型太过强烈,无法使高尔夫球手开心:)
Greg Martin

7

Mathematica,65 64字节

感谢ngenisis节省了1个字节。

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

我宁愿找到一个纯粹的模式匹配解决方案,但事实证明这很棘手(而且诸如此类{___,a__,___}的东西总是很冗长)。


4

Haskell,94个字节

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

用法示例: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

工作原理([-1,1,5,-5]供输入使用):

        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. 

powerslice是一个很棒的函数名称。
Zgarb

3

Ruby,81个字节

在线尝试

简单的暴力解决方案;对于数组的每个元素,请尝试查找包含该数组的零和切片。

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

3

J,36 35字节

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

对于每个子总和,我添加元素的索引,并保留子总和的索引0,然后检查是否存在每个索引。

技巧:列表的基于1的索引可以生成,#\即每个前缀的长度。

用法:

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

在这里在线尝试。


我认为您可以使用基于1的技巧进行求和并使用合成的展平图来节省2个字节#\*/@e.&,]({:*0=1#.{.)@|:\.\@,.#\
英里

2

JavaScript(ES6),109个字节

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)

测试片段


1

Python,123120字节

-3个字节,感谢@Zgarb

使用零和切片来填充与输入大小相同的列表,并根据索引进行覆盖,最后将其等于原始值。

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
我认为您可以使用0代替None。不会出现误报,因为0输入中的每一个始终都是部分或零和切片。
Zgarb

你是对的。我考虑了一下,但最后得出结论,它可能会产生误报。
dfernan

0

Scala,49个字节

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

在ideone上尝试

用法:

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

取消高尔夫:

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

说明:

% =>            //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
  )

我不确定这是如何工作的,但我认为在某些真实的测试用例中它应该会失败。
Zgarb

@Zgarb我添加了一个指向ideone的链接,因此您可以验证它是否正确。基本上,它是蛮力的,尝试所有可能的尝试。
corvus_192

您可以%用作参数名称吗?凉!
Cyoce

@Cyoce除以外,几乎可以使用任何Unicode字符.,;:()[]{}\"'。对于高尔夫运动来说非常有用,因为它们会被解析器与字母分开,因此您可以节省一些空格。
corvus_192

我检查了测试用例,似乎可以true证明第二个虚假的情况。
Zgarb

0

Python,86字节

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

真实= 1虚假=无


这将错误地返回1第三个测试用例。
Zgarb

1
实际上1,它会返回除前两个虚假案例以外的所有测试案例。
dfernan'1

0

Clojure,109个字节

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

生成所有总和为零的分区,并检查其是否具有“输入向量的长度”不同的索引。


0

PHP,104字节

蛮力,仍然超过99个字节。:-(

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;

接受命令行参数的输入,1对于真实,对于虚假,为空。用运行-r

分解

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]包含文件名;如果与一起运行-r,它将是数字运算符,-并且求值为0


0

JavaScript(ES6),102个字节

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)

计算i..j包含所有元素的部分和,并在找到零和时重置b1到的相关元素0,最后检查是否还1剩下。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.