내 파이가 이등분 되었습니까?


43

비어 있지 않은 양의 정수 목록을 취하는 프로그램이나 함수를 작성하십시오. "1 2 3 4"또는 과 같은 편리한 형식으로 입력되었다고 가정 할 수 있습니다 [1, 2, 3, 4].

입력 목록의 숫자는 각 조각 크기가 해당 숫자에 비례하고 모든 조각이 주어진 순서대로 차트 주위에 배열 되는 전체 원형 차트 의 조각을 나타냅니다 .

예를 들어, 파이 1 2 3 4는 다음과 같습니다.

12 34 예

코드에서 대답해야 할 질문은 다음과 같습니다 . 원형 차트가 이등분 되었습니까? 즉, 원의 한쪽에서 다른쪽으로 완벽하게 직선이 생겨 대칭으로 두 개로 분할됩니까?

당신은 필요 출력 truthy의 적어도 하나의 이등분선과 출력이있는 경우 값을 falsy 아무것도 존재하지 않는 경우는 값 .

에서 1 2 3 4예 간의 이분법 존재 4 1하고 2 3출력 truthy 것 때문에이.

그러나 입력의 1 2 3 4 5경우 이등분선이 없으므로 출력이 잘못됩니다.

12 34 예

추가 예

숫자를 다르게 배열하면 이등분선이 제거 될 수 있습니다.
예 : 2 1 3 4→ 허위 :

2 1 3 4 예

입력 목록에 하나의 숫자 만 있으면 파이는 이등분되지 않습니다.
예 : 10→ 허위 :

10 예

이등분선이 여러 개있을 수 있습니다. 0보다 많으면 출력이 진실입니다.
6 6 12 12 12 11 1 12→ 진실 : (여기에 3 개의 이등분자가 있습니다)

6 6 12 12 12 11 1 12 예

시각적으로 명확하지 않은 경우에도 이분법이 존재할 수 있습니다.
예 : 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
파이 를 의미한다고 생각 하십니까?
Alex A.

@HelkaHomba, 섹터를 재정렬하여 작동시킬 수 있습니까? "숫자를 다르게 정렬하면 이등분을 제거 할 수 있습니다"라는 의미입니까?
Solomon Ucko 2016

@SolomonUcko 섹터를 재 배열 할 수 없습니다.
Calvin 's Hobbies

1
허위 사례 중 [2 1 3 4] 만 실제로 평가해야합니다. 다른 거짓 사례는 합이 홀수이거나 길이가 <2이므로 쉽게 거부됩니다.
Benny Jobigan 2016 년

답변:


12

J, 18 바이트

Dennis 덕분에 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 의 합 이 생성 된 행렬에 속 하는지 테스트합니다 . 이 경우, 인접한 서브리스트 중 적어도 하나의 합은 전체리스트의 합의 절반과 정확히 동일하며, 이는 적어도 하나의 이등분선이 있음을 의미합니다.


15
다른 사람이 답변을하기 전에 Dennis가 5 개의 답변을 제공하는 것을 보자.
Calvin 's Hobbies

6

파이썬 2, 64 바이트

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

남아있는 항목의 합계가 삭제 된 항목의 합계와 같을 때까지 앞 또는 끝에서 요소를 반복적으로 제거하려고합니다 s. 목록 길이에서 시간이 지수로 걸립니다.

Dennis는로 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

하스켈, 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누적 합계 목록 을 생성합니다 . 그런 다음 sum l/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*σ;)-∩

온라인으로 사용해보십시오!

이 프로그램은 잘못된 경우 빈 목록을, 그렇지 않으면 비어 있지 않은 목록을 출력합니다. 본질적으로 Dennis 's Jelly 답변의 포트입니다 . 누적 합계 및 벡터화 된 차이 기능이 날짜 이후에 발생하므로 경쟁이 아닙니다.

설명:

;Σ@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

파이썬 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

오, 영리 해요 감사합니다!
Dennis

3

MATL , 10 바이트

EYst!-Gs=z

출력은 이등분 자 수입니다.

온라인으로 사용해보십시오!

설명

Dennis의 Julia 와 같은 접근 방식 .

E       % Implicit input. Multiply by 2 element-wise 
Ys      % Cumulative sum 
t!-     % Compute all pairwise differences. Gives a 2D array 
Gs      % Sum of input 
=       % Test for equality, element-wise 
z       % Number of nonzero elements. Implicit display 

3

루비, 60 53 바이트

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

입력 배열의 모든 회전을 수행 한 다음 길이가 1. 인 모든 슬라이스를 사용하여 가능한 모든 파티션을 생성합니다. n여기서 n, 입력 배열의 크기입니다. 그런 다음 입력 배열의 총 합계의 합의 절반을 가진 파티션이 있는지 확인합니다.


2

자바 스크립트 (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

파이썬 2 , 47 바이트

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

온라인으로 사용해보십시오!

새로운 방법을 사용하여 기존 솔루션 을 25 % 이상 뛰어 넘기 위해 2.75 년이 지난 지금 입니다.

이 1 바이트 더 긴 버전은 조금 더 명확합니다.

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

온라인으로 사용해보십시오!

아이디어는 누적 합계 세트 t를 비트로 저장하고 k비트 2*tt누적 합계 임을 표시하도록 설정 하는 것 입니다. 그런 다음 이 비트 를 많이 t이동 하고 원본과 k비트 단위 &로 수행 하여 결과가 0이 아닌 (트러스트) 두 누적 누적 합계가 목록 합계 (최종 )의 절반 만큼 다른지 확인합니다.


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,XX를 자체와 연결합니다. 그리고 걸릴 드롭된다.
    • +/+오른쪽에있는 목록을 축소 / 접 습니다

    따라서 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입니다. ( 대각선 맵이며 ∘.외부 제품 임)

    따라서 이것은 연결된 모든 하위 목록의 합의 두 배를 포함 ⍴X하는 ⍴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(일부 오프셋을 처리해야 할 수도 있음) 일부 바이트를 절약 할 수 있습니다 .
Leaky Nun

0

하스켈, 68 바이트

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

이 함수는 f먼저 주어진 목록에서 가능한 모든 슬라이스의 합계 목록을 만듭니다. 그런 다음 목록 요소의 총합과 비교합니다. 우리가 총합의 절반에 도달하면, 우리는 이등분이 있다는 것을 알고 있습니다. 나는 또한 당신이 경우 사실 사용하고 take또는 drop이보다 많은 요소가 목록에있는, 하스켈은 오류가 발생하지 않습니다.


0

매스 매 티카, 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는 없습니다.
Martin Ender 2016 년

@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 2 3 4. 해당 세트의이 운동 분할에 유용한 방법을 어떻게 선택할 수 있습니까? 일부 사람들은 우리가 사용할 수있는이 4 가지 요소의 파티션이 왼쪽의 이진수로 설명된다고 생각합니다.

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가 있습니다) 입력 배열의 요소 수에서 이진 숫자를 작성하는 함수 하나를 작성하는 모자 하나입니다.

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.