Apakah Pie Saya Sudah Dibelah Dua?


43

Tulis program atau fungsi yang mengambil daftar kosong bilangan bulat positif. Anda dapat menganggapnya sebagai input dalam format praktis yang wajar seperti "1 2 3 4"atau [1, 2, 3, 4].

Angka-angka dalam daftar input mewakili irisan bagan pai penuh di mana setiap ukuran irisan sebanding dengan angka yang sesuai dan semua irisan diatur di sekitar bagan dalam urutan yang diberikan.

Misalnya, kue untuk 1 2 3 4adalah:

1 2 3 4 contoh

Pertanyaan yang harus dijawab oleh kode Anda adalah: Apakah diagram lingkaran pernah dibagi dua ? Yaitu, adakah garis lurus yang sempurna dari satu sisi lingkaran ke sisi lainnya, membelahnya secara simetris menjadi dua?

Anda perlu menampilkan nilai kebenaran jika setidaknya ada satu garis-bagi dan menghasilkan nilai palsu jika tidak ada .

Dalam 1 2 3 4contoh ada pembagian dua antara 4 1dan 2 3hasilnya akan benar.

Tetapi untuk input 1 2 3 4 5tidak ada garis bagi sehingga output akan menjadi palsu:

1 2 3 4 5 contoh

Contoh tambahan

Mengatur nomor secara berbeda dapat menghapus garis bagi.
mis. 2 1 3 4→ falsy:

2 1 3 4 contoh

Jika hanya satu nomor dalam daftar input, pie tidak dibagi dua.
mis. 10→ falsy:

10 contoh

Mungkin ada beberapa garis bagi. Selama ada lebih dari nol hasilnya benar.
mis. 6 6 12 12 12 11 1 12→ truthy: (ada 3 garis-bawah di sini)

6 6 12 12 12 11 1 12 contoh

Biseksi mungkin ada bahkan jika mereka tidak jelas secara visual.
mis. 1000000 1000001→ falsy:

1000000 1000001 contoh

misalnya 1000000 1000001 1→ benar:

1000000 1000001 1 contoh

(Terima kasih kepada nces.ed.gov untuk membuat diagram lingkaran.)

Uji Kasus

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

Mencetak gol

Kode terpendek dalam byte menang. Tiebreaker adalah jawaban sebelumnya.


30
Saya percaya maksud Anda pie pai ?
Alex A.

@HelkaHomba, dapatkah Anda mengatur ulang sektor agar berfungsi, dan apakah itu yang Anda maksud dengan "mengatur angka secara berbeda dapat menghilangkan garis pemisah"?
Solomon Ucko

@SolomonUcko Anda tidak boleh mengatur ulang sektor.
Calvin Hobi

1
Hanya [2 1 3 4] dari kasus palsu yang benar-benar harus dievaluasi. Kasus palsu lainnya mudah ditolak karena jumlahnya aneh (atau panjangnya <2).
Benny Jobigan

Jawaban:


12

J, 18 byte

5 byte berkat Dennis.

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

@HelkaHomba : Tidak.

Pemakaian

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

Tidak disatukan

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

Versi 23 byte sebelumnya:

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

Pemakaian

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

Tidak disatukan

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

Penjelasan

Jumlah semua substring dihitung oleh black_magic. The +/\menghitung jumlah parsial.

Misalnya, a b c dmenjadi a a+b a+b+c a+b+c+d.

The -/~kemudian membangun sebuah meja pengurangan berdasarkan masukan, sehingga x y zmenjadi:

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

Ketika diterapkan a a+b a+b+c a+b+c+d, hasilnya adalah:

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

Ini menghitung jumlah semua substring yang tidak mengandung a.

Ini menjamin cukup, karena jika satu pembelahan berisi a, pembelahan yang lain tidak akan berisi adan juga tidak akan membungkus.


3
Dengan beberapa restrukturisasi, Anda dapat mencapai 13 byte:+/e.&,2*+/\\.
Zgarb

10

Jelly , 9 8 byte

Ḥ+\©_Sf®

Kembalikan daftar yang tidak kosong (benar) atau daftar kosong (salah). Cobalah online! atau verifikasi semua kasus uji .

Bagaimana itu bekerja

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

Terima kasih kepada @GlenO untuk bermain golf 1 byte!

Cobalah online!

Bagaimana itu bekerja

Setelah menyimpan jumlah kumulatif 2x dalam x , kita kurangi vektor baris x ' dari vektor kolom x , menghasilkan matriks dari semua perbedaan yang mungkin. Pada dasarnya, ini menghitung jumlah dari semua subarrays berdekatan x yang tidak mengandung nilai pertama, negatifnya, dan 0 's di diagonal.

Akhirnya, kami menguji apakah jumlah array asli x milik matriks yang dihasilkan. Jika ini masalahnya, jumlah setidaknya satu dari sub daftar yang berdekatan sama dengan separuh dari jumlah keseluruhan daftar, yang berarti bahwa setidaknya ada satu garis-bagi.


15
Mari kita saksikan ketika Dennis memberikan 5 jawaban sebelum orang lain memberikannya.
Calvin Hobi

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())

Secara rekursif mencoba untuk menghapus elemen dari depan atau akhir hingga jumlah yang tersisa sama dengan jumlah dari apa yang telah dihapus, yang disimpan adalah s. Membutuhkan waktu yang eksponensial dalam panjang daftar.

Dennis menyimpan 3 byte dengan pop.


Alternatif aneh yang memberikan daftar: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

Idenya adalah untuk memeriksa apakah ada sublist lyang jumlahnya sama dengan sum l/2. Kami menghasilkan jumlah dari daftar ini sebagai scanr(:)[]l>>=scanl(+)0. Mari kita lihat bagaimana ini bekerjal=[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

Lama 43 byte:

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

Menghasilkan daftar cjumlah kumulatif. Kemudian, periksa apakah ada dua dari jumlah ini yang berbeda sum l/2dengan memeriksa apakah itu merupakan elemen dari daftar perbedaan (-)<$>c<*>c.


4

Pyth, 10 9 byte

}sQmysd.:

Uji di Kompiler Pyth .

Bagaimana itu bekerja

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

Sebenarnya, 21 byte

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

Cobalah online!

Program ini mencetak 0untuk kasus yang salah, dan bilangan bulat positif untuk kasus yang benar.

Penjelasan:

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

Versi yang tidak bersaing, 10 byte

;Σ@2*σ;)-∩

Cobalah online!

Program ini menampilkan daftar kosong untuk kasus-kasus palsu dan daftar tidak kosong sebaliknya. Ini pada dasarnya adalah port jawaban Dennis's Jelly . Ini non-bersaing karena jumlah kumulatif dan fungsi perbedaan yang di-vektor-kan setelah tanggal tantangan.

Penjelasan:

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

Terima kasih kepada @xnor karena bermain golf 4 8 byte!

Uji di Ideone . (kasus uji yang lebih besar tidak termasuk)


Saya sadar Anda bisa n=sum(x)melakukannya n in ...; tidak ada salahnya menggunakan nilai yang lebih besar untuk n.
xnor

Ooh, itu pintar. Terima kasih!
Dennis

3

MATL , 10 byte

EYst!-Gs=z

Outputnya adalah jumlah garis bagi.

Cobalah online!

Penjelasan

Pendekatan yang sama dengan jawaban 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

Rubi, 60 53 byte

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

Menghasilkan semua partisi yang mungkin dengan mengambil setiap rotasi array input dan kemudian mengambil semua irisan panjang 1 .. n, di mana nukuran array input. Kemudian periksa apakah ada partisi dengan jumlah setengah jumlah total array input.


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)

Hasilkan semua jumlah yang mungkin, kemudian periksa untuk melihat apakah setengah dari jumlah terakhir (yang merupakan jumlah dari seluruh daftar) muncul dalam daftar. (Menghasilkan jumlah dalam urutan yang sedikit canggung untuk mengatur jumlah yang saya butuhkan adalah yang terakhir menghemat 4 byte.)


2

Dyalog APL, 12 byte

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

Uji dengan TryAPL .

Bagaimana itu bekerja

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

Cobalah online!

Saya kembali 2,75 tahun kemudian untuk mengalahkan solusi lama saya hingga lebih dari 25% menggunakan metode baru.

Versi 1 byte yang lebih panjang ini sedikit lebih jelas.

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

Cobalah online!

Idenya adalah untuk menyimpan set jumlah kumulatif tsebagai bit k, menetapkan bit 2*tuntuk menunjukkan bahwa itu tadalah jumlah kumulatif. Kemudian, kami memeriksa apakah ada dua jumlah kumulatif yang berbeda setengah dari jumlah daftar (final t) dengan sedikit menggeser ksebanyak ini dan melakukan sedikit demi sedikit &dengan yang asli untuk melihat hasilnya tidak nol (benar).


1

APL, 25 karakter

Dengan asumsi daftar diberikan pada X ← 1 2 3 4.

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

Penjelasan:

Catatan pertama bahwa APL mengevaluasi formulir dari kanan ke kiri. Kemudian:

  • X←⎕ mengambil input pengguna dan menyimpannya di X

  • ⍴X memberi panjang X

  • ⍳⍴X angka dari 1 hingga ⍴X

  • The dan di {2×+/⍺↑⍵↓X,X}adalah argumen kiri dan kanan untuk fungsi diad kita mendefinisikan di dalam kurung kurawal.

    • Sekarang untuk ⍺↑⍵↓X,Xbagian ini: X,Xhanya menyatukan X dengan dirinya sendiri; dan ambil dan jatuhkan.
    • +/mengurangi / melipat di +atas daftar di sebelah kanannya

    Jadi 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⍨idxhanya idx ∘.brace idx. ( adalah peta diagonal; ∘.adalah produk luar)

    Jadi ini memberi kita ⍴Xdengan ⍴Xmatriks yang berisi dua kali jumlah dari semua sublists terhubung.

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

    Hal terakhir yang harus kita lakukan adalah memeriksa apakah jumlah Xada di suatu tempat di dalam matriks ini.

  • Yang kami lakukan dengan (+/X)∊matrix.


1

C, 161 145 129 byte

  • menyimpan beberapa byte berkat @LeakyNun
  • menyimpan beberapa byte berkat @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;}

Tidak dicoba coba online

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
}

Mungkin Anda dapat menyimpan beberapa byte dengan memindahkan deklarasi variabel ke level pertama, dan mengubah i<n;i++ke i++<n(meskipun Anda mungkin perlu berurusan dengan beberapa offset.
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]

Fungsi fpertama-tama membuat daftar jumlah semua irisan yang mungkin dari daftar yang diberikan. Kemudian membandingkan dengan jumlah total elemen daftar. Jika kita mendapatkan setengah dari jumlah total, maka kita tahu bahwa kita memiliki dua bagian. Saya juga menggunakan fakta bahwa jika Anda takeatau droplebih banyak elemen dari yang ada dalam daftar, Haskell tidak membuat kesalahan.


0

Mathematica, 48 byte

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

Fungsi anonim, mirip dalam aksi dengan banyak jawaban lainnya.

Outer[Plus, #, -#], saat beraksi Accumulate@# (yang pada gilirannya bertindak pada daftar input, memberikan daftar total berturut-turut) pada dasarnya menghasilkan tabel yang sama, seperti di bagian bawah jawaban Leaky Nun.

!FreeQ[..., Last@#/2]memeriksa apakah (Last@#)/2ini tidak absen dari meja yang dihasilkan, dan Last@#merupakan yang terakhir dari jumlah berturut-turut, yaitu jumlah dari semua elemen dari daftar masukan.

Jika jawaban ini agak menarik, itu bukan karena algoritma baru, tetapi lebih banyak tentang trik khusus untuk Mathematica; misalnya !FreeQbagus, dibandingkan dengan MemberQ, karena tidak memerlukan perataan tabel yang diperiksa dan menyimpan byte.


Saya pikir !FreeQ[2Tr/@Subsequences@#,Tr@#]&harus bekerja, tetapi saya tidak akan memiliki 10,4 tersedia untuk mengujinya selama 10 hari ke depan.
Martin Ender

@ MartinEnder Sepertinya memang bekerja, tapi saya di 10.2, jadi itulah yang saya punya
LLlAMnYP

0

APL (NARS), karakter 95, byte 190

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

Pertimbangkan satu larik input 4 elemen: 1 2 3 4. Bagaimana kita dapat memilih yang berguna untuk partisi latihan set ini? Beberapa orang berpikir bahwa partisi dari 4 elemen ini dapat kita gunakan digambarkan dalam angka biner di sebelah kiri:

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

(1001 atau 1011 ecc bisa berada di set itu tetapi kita sudah memiliki 0110 dan 0100 ecc) jadi kita cukup menuliskan satu fungsi yang dari jumlah elemen array input, buat angka biner ini ... itu akan menjadi:

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

bahwa dari input 1 2 4 8 [2 ^ 0..lenBytesArgument-1] temukan 3 6 12, 7 14, 15; jadi temukan biner dari angka-angka ini dan gunakan mereka menemukan partisi yang tepat dari array input ... Saya menguji fungsi c hanya untuk itu input 4 elemen, tetapi tampaknya itu ok untuk jumlah elemen lainnya ...

uji:

  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 
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.