私のパイは二等分されましたか?


43

正の整数の空でないリストを取り込むプログラムまたは関数を作成します。"1 2 3 4"またはなどの合理的で便利な形式で入力されていると想定できます[1, 2, 3, 4]

入力リストの数値は、円グラフ全体のスライスを表します。各スライスサイズは対応する数値に比例し、すべてのスライスは指定された順序でグラフの周囲に配置されます。

たとえば、次のパイ1 2 3 4は次のとおりです。

1 2 3 4の例

あなたのコードが答えなければならない問題は、円グラフが今までされてい二分しますかつまり、円の一方の側から他方の側に完全に直線があり、対称的に2つに分割されていますか?

あなたはする必要があり、出力truthyの少なくとも一つの二等分線と出力がある場合に値をfalsy何も存在しない場合、値

1 2 3 4例との二分がある4 12 3出力truthyであろうように。

ただし、入力の1 2 3 4 5場合は二等分線がないため、出力は偽になります。

1 2 3 4 5の例

追加の例

数値を異なる方法で配置すると、二等分線が削除される場合があります。
2 1 3 4→偽:

2 1 3 4の例

入力リストに数字が1つしかない場合、パイは二等分されません。
10→偽:

10例

複数の二等分線が存在する場合があります。ゼロ以上である限り、出力は真実です。
6 6 12 12 12 11 1 12→真実:(3つの二等分線があります)

6 6 12 12 12 11 1 12例

視覚的に明らかではない場合でも、2分割が存在する場合があります。
1000000 1000001→偽:

1000000 1000001の例

1000000 1000001 1→真実:

1000000 1000001 1例

(円グラフを生成してくれたnces.ed.govに感謝します。)

テストケース

Truthy
1 2 3 4
6 6 12 12 12 11 1 12
1000000 1000001 1
1 2 3
1 1
42 42
1 17 9 13 2 7 3
3 1 2
10 20 10

Falsy
1 2 3 4 5
2 1 3 4
10
1000000 1000001
1
1 2
3 1 1
1 2 1 2 1 2
10 20 10 1

得点

バイト単位の最短コードが優先されます。Tiebreakerは以前の回答です。


30
私は、あなたは平均信じるパイが sected?
アレックスA.

@HelkaHomba、あなたはそれを機能させるためにセクターを再配置できますか?それはあなたが「数字を異なるように配置することは二等分線を削除するかもしれない」ということですか?
ソロモンウッコ

@SolomonUckoセクターを再配置することはできません。
カルビンの趣味

1
実際に評価する必要があるのは、[2 1 3 4]の誤ったケースのみです。他の偽のケースは、合計が奇数(または長さが2未満)であるため、簡単に拒否されます。
ベニージョヴィガン

回答:


12

J、18バイト

デニスのおかげで5バイト。

+/e.[:,/2*+/\-/+/\

@HelkaHomba:いいえ。

使用法

>> f =: +/e.[:,/2*+/\-/+/\
>> f 6 6 12 12 12 11 1 12
<< 4
>> f 10 20 10 1
<< 0

非ゴルフ

black_magic  =: +/\-/+/\
doubled_bm   =: 2 * black_magic
flatten      =: ,/
sum          =: +/
is_member_of =: e.
f =: sum is_member_of monadic flatten doubled_bm

以前の23バイトバージョン:

[:+/[:+/+/=+:@-/~@(+/\)

使用法

>> f =: [:+/[:+/+/=+:@-/~@(+/\)
>> f 6 6 12 12 12 11 1 12
<< 4
>> f 10 20 10 1
<< 0

非ゴルフ

black_magic =: -/~@(+/\)
double      =: +:
equals      =: =
sum         =: +/
monadic     =: [:
of          =: @
f =: monadic sum monadic sum (sum equals double of black_magic)

説明

すべてのサブストリングの合計は、black_magicによって計算されます。+/\部分和を計算します。

たとえば、にa b c dなりa a+b a+b+c a+b+c+dます。

-/~その後、入力に基づいて、減算テーブルを構築するため、x y z次のようになります。

x-x x-y x-z
y-x y-y y-z
z-x z-y z-z

に適用するa a+b a+b+c a+b+c+dと、結果は次のようになります。

    0  -b -b-c -b-c-d
    b   0   -c   -c-d
  b+c   c    0     -d
b+c+d c+d    d      0

これは、を含まないすべての部分文字列の合計を計算しましたa

これは十分であることを保証します。一方の二分法がを含むa場合、もう一方の二分法は含まれaず、ラップアラウンドもしません。


3
いくつかの再構築により、13バイトを取得できます+/e.&,2*+/\\.
。– Zgarb

10

ゼリー9 8 バイト

Ḥ+\©_Sf®

空でないリスト(真)または空のリスト(偽)を返します。オンラインでお試しください!または、すべてのテストケースを確認します

使い方

Ḥ+\©_Sf®  Main link. Argument: A (list)

Ḥ         Double all integers in A.
 +\       Take the cumulative sum of 2A.
   ©      Copy; store the result in the register.
    _S    Subtract the sum of A from each partial sum of 2A.
      f®  Filter; intersect this list with the list in the register.

7

ジュリア、34 30 29バイト

!x=sum(x)∈cumsum!(x,2x).-x'

1バイトのゴルフをしてくれた@GlenOに感謝します!

オンラインでお試しください!

使い方

累積和格納した後に2倍Xは、我々は、行ベクトル減算X」の列ベクトルからXを全ての可能な差の行列が得られます。基本的に、これは、最初の値、それらの負の値、および対角に0を含まないxのすべての隣接するサブ配列の合計を計算します。

最後に、元の配列xの合計が生成された行列に属するかどうかをテストします。この場合、少なくとも1つの隣接サブリストの合計は、リスト全体の合計のちょうど半分に等しくなります。これは、少なくとも1つの二等分線があることを意味します。


15
デニスが他の誰かが答える前に5つの答えを与えるのを見てみましょう。
カルビンの趣味

6

Python 2、64バイト

f=lambda l,s=0:l>[]and(sum(l)==s)|f(l[1:],s+l[0])|f(l,s+l.pop())

残っているものの合計が削除されたものの合計と等しくなるまで、再帰的にフロントまたはエンドから要素を削除しようとしsます。リストの長さで指数関数的な時間がかかります。

デニスはで3バイトを節約しましたpop


リストを提供する奇妙な選択肢:f=lambda l,s=0:l and(sum(l)==s)*l+f(l[1:],s+l[0])+f(l,s+l.pop())
xnor

5

Haskell、41バイト

f l=elem(sum l/2)$scanr(:)[]l>>=scanl(+)0

考え方はl、合計が等しいサブリストがあるかどうかをチェックすることですsum l/2。これらのサブリストの合計をとして生成しscanr(:)[]l>>=scanl(+)0ます。これがどのように機能するか見てみましょうl=[1,2,3]

>> scanr(:)[]l
[[1,2,3],[2,3],[3],[]] 
-- the suffixes of l

>> scanl(+)0 [2,3,4]
[0,2,5,9]
-- the cumulative sums of the input

>> scanr(:)[]l>>=scanl(+)0
[0,1,3,6,0,2,5,0,3,0]
-- the cumulative sums of the suffixes of l, flattened to a single list

古い43バイト:

f l|c<-scanl1(+)l=elem(sum l/2)$(-)<$>c<*>c

c累積合計のリストを生成します。次に、これらの合計のいずれか2つが相違点sum l/2のリストの要素であるかどうかを確認することにより、これらの合計の2つが異なるかどうかを確認します(-)<$>c<*>c


4

Pyth、10 9バイト

}sQmysd.:

Pyth Compilerでテストします。

使い方

       .:  Generate the list of all adjacent sublists.
   m       Map over the result:
     sd       Add the integers of the sublist.
    y         Double the sum.
 sQ        Compute the sum of the input.
}          Check if it belongs to the list of doubled sublist sums.

4

実際には、21バイト

;Σ@2*;lR@τ╗`╜V♂Σi`Míu

オンラインでお試しください!

このプログラムは0、偽の場合はを、真の場合は正の整数を出力します。

説明:

;Σ@2*;lR@τ╗`╜V♂Σi`Míu
;Σ                     sum of copy of input
  @2*                  double values in other copy
     ;lR               copy, range(1, len(input)+1)
        @τ             append other copy to itself
          ╗            save in reg0
           `╜V♂Σi`M    map: generate cyclic cumulative sums
                   íu  1-based index of sum of input (0 if not found)

非競合バージョン、10バイト

;Σ@2*σ;)-∩

オンラインでお試しください!

このプログラムは、偽の場合は空のリストを出力し、そうでない場合は空でないリストを出力します。それは本質的にデニスのゼリーの答えのポートです。累積的な合計機能とベクトル化された差分機能がチャレンジより後の日付であるため、競合しません。

説明:

;Σ@2*σ;)-∩
;Σ          sum of copy of input
  @2*       multiply values in other copy by 2
     σ;     two copies of cumulative sum
       )-   subtract sum of input from each element in one copy
         ∩  set intersection with other copy

4

Python 2、76 74 70 66バイト

def f(x):n=sum(x);print n in[2*sum(x[k/n:k%n])for k in range(n*n)]

4 8バイトのゴルフをしてくれた@xnorに感謝します!

Ideoneでテストします。(より大きなテストケースは除外)


私はあなたが行うことができます実現n=sum(x)行うことn in ...。に大きな値を使用しても問題ありませんn
xnor

ああ、それは賢い。ありがとうございました!
デニス


3

ルビー、 60 53バイト

->a{a.any?{r=eval a*?+;a.rotate!.any?{|i|0==r-=2*i}}}

入力配列のすべての回転を取得し、長さ1 ..のすべてのスライスを取得することにより、可能なすべてのパーティションを生成します。nここnで、は入力配列のサイズです。次に、入力配列の合計の半分の合計を持つパーティションが存在するかどうかを確認します。


2

JavaScript(ES6)、83バイト

a=>a.map(_=>a.slice(--n).map(m=>s.push(t+=m),t=0),s=[],n=a.length)&&s.includes(t/2)

すべての可能な合計を生成し、最後の合計の半分(リスト全体の合計)がリストに表示されるかどうかを確認します。(最後に必要な合計を調整するために少し厄介な順序で合計を生成すると、4バイト節約されます。)


2

Dyalog APL、12バイト

+/∊2×+\∘.-+\

TryAPLでテストします

使い方

+/∊2×+\∘.-+\  Monadic function train. Right argument: y (vector)

     +\   +\  Yield the cumulative sum of y.
       ∘.-    Compute all differences of all partial sums.
              This computes the sums of all adjacent subvectors of y that do not
              contain the first value, their negatives, and 0's in the diagonal.
   2×         Multiply all differences by 2.
+/            Yield the sum of y.
  ∊           Test for membership.

2

Python 2、47バイト

k=t=1
for x in input():t<<=x;k|=t*t
print k&k/t

オンラインでお試しください!

2 .75 年後、新しい方法を使用して、古いソリューションを25%以上上回ることができました。

この1バイトの長いバージョンは、もう少し明確です。

k=t=0
for x in input():t+=x;k|=4**t
print k&k>>t

オンラインでお試しください!

考え方は、累積和のセットをのtビットとして保存し、ビットが累積和であることを示すようにkビット2*tを設定することですt。次に、2つの累積合計がリスト合計の半分(最終t)だけ異なるかどうかを確認します。kこれをビットシフト&し、元のビットをビット単位で実行して、結果がゼロ以外(真)であることを確認します。


1

APL、25文字

リストがで与えられていると仮定しX ← 1 2 3 4ます。

(+/X)∊∘.{2×+/⍺↑⍵↓X,X}⍨⍳⍴X←⎕

説明:

最初に、APLはフォームを右から左に評価することに注意してください。次に:

  • X←⎕ ユーザー入力を取得して保存します X

  • ⍴X の長さを与える X

  • ⍳⍴X 1からの数字 ⍴X

  • 我々は、中括弧の内側に定義されている二項関数の左と右の引数です。{2×+/⍺↑⍵↓X,X}

    • 今の⍺↑⍵↓X,X一部: X,Xちょうど自分自身でXを連結し、そして、取ると、ドロップされます。
    • +/+右側のリストを縮小/折りたたみます

    だから2 {2×+/⍺↑⍵↓X,X} 1= 2×+/2↑1↓X,X= 2×+/2↑1↓1 2 3 4 1 2 3 4=

    = 2×+/2↑2 3 4 1 2 3 4= 2×+/2 3= 2×5= 10

  • ∘.brace⍨idxただidx ∘.brace idxです。(対角線図、∘.外積)

    したがって、これにより、接続されたすべてのサブリストの2倍の合計を含む⍴Xby ⍴Xマトリックスが得られます。

     4  6  8  2
    10 14 10  6
    18 16 14 12
    20 20 20 20
    

    最後にすべきことは、合計がXこのマトリックス内のどこかにあるかどうかを確認することです。

  • 私たちはこれを行います(+/X)∊matrix


1

C、161 145 129バイト

  • @LeakyNunのおかげで数バイト節約
  • @ceilingcatのおかげで数バイト節約
i;j;k;t;r;s;f(x,n)int*x;{for(t=i=k=r=0;i<n;)t+=x[i++];for(;++k<n;i=n)for(;i--;r|=2*s==t)for(s=0,j=i;j<i+k;)s+=x[j++%n];return r;}

Ungolfed オンラインしてみてください

int f(int*x,int n)
{
    int t=0;

    for(int i=0;i<n;i++)
    {
        t += x[i];
    }

    for(int k=1;k<n;k++) // subset-size
    {
        for(int i=0,s;i<n;i++) // where to start
        {
            s=0;

            for(int j=i;j<i+k;j++) // sum the subset
            {
                s+=x[j%n];
            }

            if(2*s==t) return 1; // TRUE
        }
    }

    return 0; // FALSE
}

おそらく、あなたが最初のレベルに変数の宣言を移動し、変更することで、いくつかのバイトを保存することができますi<n;i++i++<nあなたには、いくつかのオフセットに対処する必要があるかもしれませんが(。
漏れ修道女

0

Haskell、68バイト

f l|x<-[0..length l]=any(sum l==)[2*(sum$take a$drop b l)|a<-x,b<-x]

この関数はf最初に、指定されたリストのすべての可能なスライスの合計のリストを作成します。次に、リスト要素の合計と比較します。合計の半分のポイントに到達した場合、二等分していることがわかります。また、リストに存在する要素takeまたはdropそれ以上の要素がある場合、Haskellはエラーをスローしないという事実も使用しています。


0

Mathematica、48バイト

!FreeQ[Outer[Plus,#,-#],Last@#/2]&@Accumulate@#&

他の多くの回答と動作が似ている匿名機能。

Outer[Plus, #, -#]、に作用するとAccumulate@#(入力リストに作用し、連続した合計のリストを提供します)、Leaky Nunの答えの下部と本質的に同じテーブルを生成します。

!FreeQ[..., Last@#/2]か否かをチェックが(Last@#)/2ありません結果のテーブルに存在しないと、Last@#すなわち、入力リストのすべての要素の和、連続合計の最後です。

この答えがやや興味深い場合、それは新しいアルゴリズムによるものではなく、Mathematicaに特有のトリックに関するものです。例えば!FreeQに比べて、いいですMemberQ、それはそれをチェックし、テーブルの平坦化を必要としないので、そしてそれはバイトを保存します。


私が思うに!FreeQ[2Tr/@Subsequences@#,Tr@#]&動作するはずですが、私は次の10日かそこらのためにそれをテストするために利用できる10.4を持っていません。
マーティンエンダー

@MartinEnder確かにうまくいくように見えますが、私は10.2にいるので、それが私が持っているものです
-LLlAMnYP

0

APL(NARS)、文字95、バイト190

{1≥k←≢w←⍵:0⋄s←+/⍵⋄∨/{s=2×s-+/⍵}¨↑¨{⍵⊂w}¨{(k⍴2)⊤⍵}¨{1≥≢⍵:⍵⋄⍵,∇{(1+2×(↑⍵))×2*0..¯2+≢⍵}⍵}2*0..k-1}

4つの要素の入力の1つの配列を考えます。1 2 3 4.そのセットのこのエクササイズパーティションに役立つものをどのように選択できますか?さらに、使用できるこれらの4つの要素のパーティションは、左側の2進数で記述されていると考える人もいます。

0001,0010,0100,1000 2^(0..4) 1 2 4  8 
0011,0110,1100,                3 6 12
0111,1110,                       7 14
1111                               15

(1001または1011 eccがそのセットに含まれる可能性がありますが、すでに0110および0100 eccがあります)したがって、入力配列の要素の数からこれらの2進数を作成する関数を1つ書くだけでいいのです。

c←{1≥≢⍵:⍵⋄⍵,∇{(1+2×(↑⍵))×2*0..¯2+≢⍵}⍵}

入力1 2 4 8 [2 ^ 0..lenBytesArgument-1]から3 6 12、7 14、15を見つける。したがって、これらの数値のバイナリを見つけ、それらを使用して入力配列の適切なパーティションを見つけます...私はその入力4要素についてのみc関数をテストしましたが、他の要素数については問題ないようです...

テスト:

  f←{1≥k←≢w←⍵:0⋄s←+/⍵⋄∨/{s=2×s-+/⍵}¨↑¨{⍵⊂w}¨{(k⍴2)⊤⍵}¨{1≥≢⍵:⍵⋄⍵,∇{(1+2×(↑⍵))×2*0..¯2+≢⍵}⍵}2*0..k-1}
  f¨(1 2 3 4)(6 6 12 12 12 11 1 12)(1000000 1000001 1)(1 2 3)(1 1)(42 42)
1 1 1 1 1 1 
  f¨(1 2 3 4 5)(2 1 3 4)(,10)(1000000 1000001)(,1)(1 2)(3 1 1)
0 0 0 0 0 0 0 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.