ゼロサムカバー


38

前書き

整数の空でないリストLを考えます。ゼロサムスライスLは、の連続サブシーケンスであるL、その和例えば0に等しい、[1、-3、2]のゼロ和スライスである[-2、4、1、-3、2,2 、-1、-1]ですが、[2、2]は(合計が0にならないため)ではなく、[4、-3、-1]にもなりません(隣接していないため)。

ゼロ和スライスの集合LがあるゼロサムカバーLすべての要素は、スライスの少なくとも一つに属する場合。例えば:

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

3つのゼロサムスライスAB、およびCは、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、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
3番目の偽の例[2,2,-1,-1,0,1] -> Falseは、両方のスライス[2,-1,-1][-1,0,1]ゼロに追加され、それらのすべての要素が元のリストにあるため、真実ではありませんか?
-dfernan

左端の2は、ゼロサムスライスの一部ではありません。少し不明瞭ですが、「インデックスを含む」スライスで発生する必要があります。
ズガーブ

わかった。それは難しくなります。:o)
dfernan

回答:


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バイトを節約し、将来の新しいトリックを学んだことを願っています!

2つの等しく長い無名の関数であり、どちらの選択肢、入力として整数のリストを取得し、返しますTrueFalse

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}]として、これらすべてのスライス合計を倍数します。(入力リスト内のすべての累乗の合計、つまり単にリストの長さを定義することに注意してください。)つまり、この積は0 番目の要素がゼロサムスライスに属する場合にのみ0になります。 。ikjkl=Tr[1^#]l1k

最初のバージョンでは、これらの製品はそれぞれと比較され0、すべての製品がに等しいときに正確にAnd@@戻ります。2番目のバージョンでは、製品のリストは関数(- 次元ベクトルの長さ)の影響を受けます。この関数は、すべてのエントリがに等しい場合にのみ等しくなります。True0Norml00


1
Tr[1^#]1からバイトを保存しますLength@#
-ngenisis

0^の代わりに働きますか0==?Mathematicaがそれをどのように処理するかわからない。(1/の0代わりにtrue/ を返すfalse
チョイス

1
素晴らしいアイデアですが、MathematicaはIndeterminateを返します0^0。また、1/ 0では実際にMathematicaで真実/偽りではありません。ゴルファーを幸せにするために強く打ち込まれています:)
グレッグマーティン

7

Mathematica、65 64バイト

1バイトを節約してくれたngenisisに感謝します。

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バイト

@Zgarbのおかげで-3バイト

入力と同じサイズのリストにゼロサムスライスを設定し、インデックスに従って上書きし、最後に元の同等性を返します。

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代わりにプレースホルダーとして使用できると思いますNone0入力のすべてが常に一部またはゼロサムスライスであるため、誤検出はありません。
ズガルブ

あなたが正しいです。私はそれについて考えましたが、それは誤検知を招く可能性があると結論付けました。
-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を除くほとんどのUnicode文字を使用できます.,;:()[]{}\"'。解析により文字と分離されるため、ゴルフに非常に役立ちます。そのため、空白を節約できます。
-corvus_192

私はテストケースをチェックしました、そして、それtrueは2番目の偽のケースを与えているようです。
-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

Truthy = 1 Falsy = None


これ1は、3番目のテストケースに対して誤って返されます。
ズガルブ

1
実際には1、最初の2つの偽のケースを除くすべてのテストケースに戻ります。
-dfernan

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包括し、そしての関連する要素リセットbからを1する0、それが最終的に何が存在しないことを確認し、ゼロ合計を見つけたときに1左Sが。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.