Bánh của tôi đã bị bẻ khóa?


43

Viết chương trình hoặc hàm có trong danh sách số nguyên dương. Bạn có thể cho rằng nó là đầu vào trong một định dạng thuận tiện hợp lý như "1 2 3 4"hoặc [1, 2, 3, 4].

Các số trong danh sách đầu vào biểu thị các lát của biểu đồ hình tròn đầy đủ trong đó mỗi kích thước lát tỷ lệ với số tương ứng của nó và tất cả các lát được sắp xếp xung quanh biểu đồ theo thứ tự cho trước.

Ví dụ, chiếc bánh cho 1 2 3 4:

1 2 3 4 ví dụ

Câu hỏi mà mã của bạn phải trả lời là: Biểu đồ hình tròn có bị cắt đôi không? Đó là, có bao giờ một đường thẳng hoàn hảo từ một bên của vòng tròn sang bên kia, chia nó đối xứng thành hai?

Bạn cần phải ra một truthy giá trị nếu có ít nhất một phân giác và đầu ra một falsy giá trị nếu có không .

Trong 1 2 3 4ví dụ này có một sự phân chia giữa 4 12 3do đó đầu ra sẽ là sự thật.

Nhưng đối với đầu vào 1 2 3 4 5không có bisector nên đầu ra sẽ bị sai lệch:

1 2 3 4 5 ví dụ

Ví dụ bổ sung

Sắp xếp các số khác nhau có thể loại bỏ bisector.
ví dụ 2 1 3 4→ giả

2 1 3 4 ví dụ

Nếu chỉ có một số trong danh sách đầu vào, chiếc bánh không bị cắt đôi.
ví dụ 10→ giả

10 ví dụ

Có thể có nhiều người chia nhỏ. Miễn là có nhiều hơn 0 thì đầu ra là trung thực.
ví dụ 6 6 12 12 12 11 1 12→ sự thật: (có 3 người chia nhỏ ở đây)

6 6 12 12 12 11 1 12 ví dụ

Sự sai lệch có thể tồn tại ngay cả khi chúng không rõ ràng.
ví dụ 1000000 1000001→ giả

1000000 1000001 ví dụ

ví dụ 1000000 1000001 1→ sự thật:

1000000 1000001 1 ví dụ

(Cảm ơn nces.ed.gov vì đã tạo các biểu đồ hình tròn.)

Các trường hợp thử nghiệm

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

Chấm điểm

Mã ngắn nhất tính bằng byte thắng. Tiebreaker là câu trả lời trước đó.


30
Tôi tin rằng bạn có nghĩa là bánh nướng ?
Alex A.

@HelkaHomba, bạn có thể sắp xếp lại các lĩnh vực để làm cho nó hoạt động không, và đó có phải là ý của bạn bằng cách "sắp xếp các số khác nhau có thể loại bỏ bisector" không?
Solomon Ucko

@SolomonUcko Bạn không được sắp xếp lại các lĩnh vực.
Sở thích của Calvin

1
Chỉ [2 1 3 4] trong số các trường hợp sai phải thực sự được đánh giá. Các trường hợp sai khác dễ dàng bị từ chối vì tổng của chúng là số lẻ (hoặc độ dài của chúng là <2).
Benny Jobigan

Câu trả lời:


12

J, 18 byte

5 byte nhờ Dennis.

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

@HelkaHomba : Không.

Sử dụng

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

Bị đánh cắp

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

Phiên bản 23 byte trước:

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

Sử dụng

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

Bị đánh cắp

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

Giải trình

Tổng của tất cả các chuỗi con được tính bởi black_magic. Việc +/\tính tổng một phần.

Ví dụ, a b c dtrở thành a a+b a+b+c a+b+c+d.

Sau -/~đó, xây dựng một bảng trừ dựa trên đầu vào, do đó x y ztrở thành:

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

Khi áp dụng a a+b a+b+c a+b+c+d, kết quả sẽ là:

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

Điều này đã tính tổng của tất cả các chuỗi con không chứa a.

Điều này đảm bảo là đủ, vì nếu một phần có chứa a, phần chia kia sẽ không chứa avà cũng sẽ không bao quanh.


3
Với một số cấu trúc lại, bạn có thể nhận được tới 13 byte:+/e.&,2*+/\\.
Zgarb

10

Thạch , 9 8 byte

Ḥ+\©_Sf®

Trả về một danh sách không trống (trung thực) hoặc một danh sách trống (giả). Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

Làm thế nào nó hoạt động

Ḥ+\©_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

Julia, 34 30 29 byte

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

Cảm ơn @GlenO vì đã chơi golf 1 byte!

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

Sau khi lưu trữ tổng tích lũy của 2x trong x , chúng tôi loại trừ vector hàng x' từ vectơ cột x , năng suất ma trận của tất cả các sự khác biệt có thể. Về cơ bản, phần này tính tổng của tất cả các phần tử con liền kề của x không chứa giá trị đầu tiên, phần phủ định của chúng và 0 'theo đường chéo.

Cuối cùng, chúng tôi kiểm tra xem tổng của mảng ban đầu x có thuộc về ma trận được tạo không. Nếu đây là trường hợp, tổng của ít nhất một trong các danh sách con liền kề bằng một nửa chính xác của toàn bộ danh sách, có nghĩa là có ít nhất một bisector.


15
Hãy xem Dennis đưa ra 5 câu trả lời trước khi bất kỳ ai khác đưa ra một câu trả lời.
Sở thích của Calvin

6

Python 2, 64 byte

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

Đệ quy cố gắng loại bỏ các phần tử từ phía trước hoặc kết thúc cho đến khi tổng của những gì còn lại bằng tổng của những gì đã bị xóa, được lưu trữ là s. Mất thời gian theo cấp số nhân trong chiều dài danh sách.

Dennis lưu 3 byte với pop.


Một thay thế kỳ lạ cung cấp danh sách: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 byte

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

Ý tưởng là để kiểm tra xem có một danh sách con lcó tổng bằng không sum l/2. Chúng tôi tạo ra tổng của các danh sách con như scanr(:)[]l>>=scanl(+)0. Hãy xem cách nó hoạt động vớil=[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 byte cũ:

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

Tạo danh sách ccác khoản tiền tích lũy. Sau đó, kiểm tra xem có bất kỳ hai trong số các khoản tiền này khác nhau hay không bằng sum l/2cách kiểm tra xem đó có phải là một yếu tố của danh sách khác biệt hay không (-)<$>c<*>c.


4

Bình thường, 10 9 byte

}sQmysd.:

Kiểm tra nó trong Trình biên dịch Pyth .

Làm thế nào nó hoạt động

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

Trên thực tế, 21 byte

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

Hãy thử trực tuyến!

Chương trình này in ra một 0trường hợp sai và số nguyên dương cho trường hợp đúng.

Giải trình:

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

Phiên bản không cạnh tranh, 10 byte

;Σ@2*σ;)-∩

Hãy thử trực tuyến!

Chương trình này đưa ra một danh sách trống cho các trường hợp sai và một danh sách không trống khác. Nó thực chất là một cổng của câu trả lời Jelly của Dennis . Nó không cạnh tranh bởi vì tổng tích lũy và chức năng khác biệt được vector hóa sau ngày thử thách.

Giải trình:

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

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

Cảm ơn @xnor vì đã chơi golf 4 8 byte!

Kiểm tra nó trên Ideone . (loại trừ trường hợp thử nghiệm lớn hơn)


Tôi nhận ra bạn có thể làm n=sum(x)để làm n in ...; không đau khi sử dụng giá trị lớn hơn cho n.
xnor

Ôi, thật là thông minh. Cảm ơn bạn!
Dennis

3

MATL , 10 byte

EYst!-Gs=z

Đầu ra là số lượng chia nhỏ.

Hãy thử trực tuyến!

Giải trình

Cách tiếp cận tương tự như câu trả lời của 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

Hồng ngọc 60 53 byte

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

Tạo tất cả các phân vùng có thể bằng cách lấy mọi vòng quay của mảng đầu vào và sau đó lấy tất cả các lát có độ dài 1 .. n, trong đó nkích thước của mảng đầu vào. Sau đó kiểm tra xem có tồn tại bất kỳ phân vùng nào với tổng bằng một nửa tổng của mảng đầu vào không.


2

JavaScript (ES6), 83 byte

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

Tạo tất cả các khoản tiền có thể, sau đó kiểm tra xem liệu một nửa số tiền cuối cùng (là tổng của toàn bộ danh sách) có xuất hiện trong danh sách hay không. (Tạo các khoản tiền theo thứ tự hơi khó xử để sắp xếp số tiền tôi cần để cuối cùng tiết kiệm 4 byte.)


2

APL Dyalog, 12 byte

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

Kiểm tra nó với TryAPL .

Làm thế nào nó hoạt động

+/∊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 byte

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

Hãy thử trực tuyến!

Tôi trở lại 2,75 năm sau để đánh bại giải pháp cũ của tôi hơn 25% bằng phương pháp mới.

Phiên bản dài hơn 1 byte này rõ ràng hơn một chút.

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

Hãy thử trực tuyến!

Ý tưởng là lưu trữ tập hợp các khoản tiền tích lũy tdưới dạng bit của k, thiết lập bit 2*tđể chỉ ra đó tlà tổng tích lũy. Sau đó, chúng tôi kiểm tra xem có bất kỳ hai tổng tích lũy nào khác nhau một nửa tổng số danh sách (cuối cùng t) hay không bằng cách dịch chuyển bit knày nhiều và thực hiện theo bit &với bản gốc để xem kết quả là khác không (trung thực).


1

APL, 25 ký tự

Giả sử danh sách được đưa ra trong X ← 1 2 3 4.

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

Giải trình:

Đầu tiên lưu ý rằng APL đánh giá biểu mẫu từ phải sang trái. Sau đó:

  • X←⎕ lấy đầu vào của người dùng và lưu trữ nó trong X

  • ⍴X cho chiều dài của X

  • ⍳⍴X các số từ 1 đến ⍴X

  • Đối số và bên trong {2×+/⍺↑⍵↓X,X}là đối số trái và phải đối với hàm dyadic mà chúng ta đang xác định bên trong dấu ngoặc nhọn.

    • Bây giờ về ⍺↑⍵↓X,Xphần: X,Xchỉ ghép X với chính nó; được lấy và thả.
    • +/giảm / gấp +so với danh sách bên phải của nó

    Vậy 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⍨idxchỉ là idx ∘.brace idx. ( là bản đồ đường chéo; ∘.là sản phẩm bên ngoài)

    Vì vậy, điều này mang lại cho chúng ta một ⍴Xbằng ⍴Xma trận, trong đó có hai lần số tiền của tất cả các danh sách con được kết nối.

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

    Điều cuối cùng chúng ta phải làm là kiểm tra xem tổng của Xcó ở đâu đó trong ma trận này không.

  • Mà chúng tôi làm với (+/X)∊matrix.


1

C, 161 145 129 byte

  • đã lưu vài byte nhờ @LeakyNun
  • đã lưu vài byte nhờ @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 thử trực tuyến

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
}

Có lẽ bạn có thể lưu một số byte bằng cách di chuyển các khai báo của các biến sang cấp độ đầu tiên và thay đổi i<n;i++thành i++<n(mặc dù bạn có thể cần phải xử lý một số bù đắp.
Leaky Nun

0

Haskell, 68 byte

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

Hàm ftrước tiên tạo một danh sách tổng của tất cả các lát có thể có của danh sách đã cho. Sau đó, nó so sánh với tổng số các yếu tố danh sách. Nếu chúng tôi nhận được tại một số điểm trong tổng số điểm, thì chúng tôi biết rằng chúng tôi đã có một sự chia đôi. Tôi cũng đang sử dụng thực tế là nếu bạn takehoặc dropnhiều yếu tố hơn trong danh sách, Haskell không đưa ra lỗi.


0

Toán học, 48 byte

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

Chức năng ẩn danh, tương tự như trong nhiều câu trả lời khác.

Outer[Plus, #, -#], khi hành động Accumulate@#(lần lượt tác động vào danh sách đầu vào, đưa ra danh sách tổng số liên tiếp) sẽ tạo ra cùng một bảng, như ở cuối câu trả lời của Leaky Nun.

!FreeQ[..., Last@#/2]kiểm tra nếu (Last@#)/2không vắng mặt trong bảng kết quả, và Last@#là người cuối cùng trong những tổng số liên tiếp, tức là tổng của tất cả các yếu tố của danh sách đầu vào.

Nếu câu trả lời này có phần thú vị, thì đó không phải là vì một thuật toán mới, mà là về các thủ thuật dành riêng cho Mathicala; ví dụ, !FreeQlà tốt, so với MemberQ, vì nó không yêu cầu làm phẳng bảng mà nó kiểm tra nó tiết kiệm một byte.


Tôi nghĩ !FreeQ[2Tr/@Subsequences@#,Tr@#]&nên làm việc, nhưng tôi sẽ không có sẵn 10,4 để thử nghiệm trong 10 ngày tới.
Martin Ender

@MartinEnder Có vẻ như nó hoạt động, nhưng tôi vào ngày 10.2, vì vậy đó là những gì tôi có
LLlAMnYP

0

APL (NARS), ký tự 95, byte 190

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

Xem xét một mảng đầu vào gồm 4 phần tử: 1 2 3 4. Làm thế nào chúng ta có thể chọn hữu ích cho phân vùng bài tập này của tập hợp đó? Tuy nhiên, một số người cho rằng phân vùng của 4 yếu tố này mà chúng ta có thể sử dụng được giải thích trong số nhị phân bên trái:

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

(1001 hoặc 1011 ecc có thể nằm trong tập hợp đó nhưng chúng ta đã có 0110 và 0100 ecc) vì vậy một chiếc mũ chỉ để viết một hàm mà từ số phần tử của mảng đầu vào xây dựng các số nhị phân này ... đó sẽ là:

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

rằng từ đầu vào 1 2 4 8 [2 ^ 0..lenBytesArgument-1] tìm 3 6 12, 7 14, 15; vì vậy hãy tìm nhị phân của các số này và sử dụng chúng để tìm đúng phân vùng của mảng đầu vào ... Tôi chỉ kiểm tra hàm c cho 4 phần tử đầu vào đó, nhưng có vẻ như nó ổn với số phần tử khác ...

kiểm tra:

  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 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.