Hitung persegi panjang dalam kotak diagonal

21

Sebagai tindak lanjut dari tantangan ini , kami sekarang ingin menghitung jumlah persegi panjang dalam grid dengan r baris dan kolom c di mana ada garis yang melintasi setiap diagonal dari sebuah persegi di grid. Sekarang, kami masih menghitung persegi panjang yang sama seperti sebelumnya, tapi kali ini kami juga harus memasukkan persegi panjang yang dimiringkan 45 derajat.

Tujuan Anda adalah membuat fungsi atau program yang memberikan jumlah baris r dan kolom c menghasilkan jumlah persegi panjang dalam kisi diagonal dengan dimensi ( r , c ).

Sebagai demonstrasi, ini adalah animasi yang diputar melalui semua 37 persegi panjang yang dibentuk oleh kisi diagonal (2 x 3).

Contoh

Uji Kasus

Each case is [rows, columns] = # of rectangles
[0, 0] = 0
[0, 1] = 0
[1, 0] = 0
[1, 1] = 1
[3, 2] = 37
[2, 3] = 37
[6, 8] = 2183
[7, 11] = 5257
[18, 12] = 40932
[42, 42] = 2889558
[51, 72] = 11708274

Aturan

  • Ini adalah sehingga kode terpendek menang.
  • Orang bawaan yang memecahkan masalah ini tidak diizinkan.
mil
sumber
7
Hanya Mathematica yang dapat memiliki builtin untuk XD ini
Conor O'Brien
3
Astaga, ini jauh lebih sulit daripada yang persegi panjang lainnya .....
GamrCorps
5
Lihat tantangan terkait projecteuler.net/problem=147
Marcus Andrews
1
Saya pikir built-in harus diizinkan. Saya suka melihat jawaban itu.
mbomb007

Jawaban:

8

Ruby, 58 byte

Ini adalah implementasi langsung dari algoritma dalam Melepaskan jawaban C Helium Nuclei .

g=->m,n{n>m ?g[n,m]:m*~m*n*~n/4+n*((2*m-n)*(4*n*n-1)-3)/6}

Saya telah menyelidiki mengapa formula ini bekerja, dengan keberhasilan yang terbatas. Sangat mudah untuk mengkonfirmasi bahwa jumlah persegi panjang tegak sama dengan (m+1)*m/2 * (n+1)*n/2, jumlah persegi panjang diagonal sedikit lebih sulit dipahami.

Neil punya dikonfirmasi untuk m==nbahwa jumlah persegi panjang miring dalam n*npersegi (4*n**4-n*n-3*n)/6dan bahwa ketika m>n Anda perlu menambahkan tambahan (m-n)(n*(4*n*n-1)/3)(terkait dengan Oei A000447 ), meskipun ini tidak menjelaskan di mana dua formula berasal. Saya telah menemukan bagian dari jawabannya.

Sebab m==n, bentuk di dalam grid adalah berlian Aztec .

Gambar Aztec Diamond dari Wolfram Alpha

Jumlah persegi panjang dalam berlian Aztec adalah jumlah dari jumlah persegi panjang besar ditumpangkan untuk membuatnya (untuk diamond keempat, yang ditemukan dalam 5x5grid, 2x8, 4x6, 6x4, dan 8x2) dikurangi jumlah persegi panjang dihitung dua kali (jumlah persegi panjang di berlian Aztec sebelumnya ).

Rumusnya di sini adalah (TeX akan ditambahkan nanti):

# superimposed rectangles, 2x(2n-2), 4*(2n-4), ...
f = lambda n: sum( (2*k)*(2*k+1)/2 * (2*n-2*k)*(2*n-2*k+1)/2 for k in range(1, n) )
aztec_rect = f(n) - f(n-1)

Menurut Wolfram Alpha, bentuk tertutup untuk fadalah 1/30*(n-1)*n*(4*n**3+14*n**2+19*n+9)dan bentuk tertutup aztec_rectadalah, seperti yang ditemukan Neil 1/6*n*(n-1)*(4*n**2+4*n+3) == 1/6*(4*n**4-n**2-3*n),.

Saya belum menemukan alasannya (m-n)(n*(4*n*n-1)/3) bekerja, meskipun saya curiga itu karena satu definisi A000447 adalah binomial(2*n+1, 3). Saya akan membuat Anda tetap diposting.

Memperbarui: Saya punya alasan untuk percaya bahwa fungsi jumlah persegi panjang pada berlian Aztec yang diperluas m>nterkait dengan jumlah 2k*2(n-k)persegi panjang yang dilapiskan pada minus berlian F(m-1,n-1). Lebih banyak hasil ketika saya memilikinya.

Pembaruan: Saya mencoba rute yang berbeda dan berakhir dengan formula lain untuk berlian Aztec tambahan yang sebagian besar dapat dijelaskan tetapi memiliki satu istilah yang belum saya mengerti. Sabas! : D

def f(m,n):
 if n > m:
     return f(n,m)
 if n == 0:
     return 0
 else:
     return(m-n+1)*(4*n**4-n*n-3*n)/6-f(m-1,n-1)+(m-n)*2+(m-n)*(n-2)-(m-n-1)*f(n-1,n-1)

Rincian cepat dari formula terakhir itu:

  • (m-n+1)*(4*n**4-n*n-3*n)/6adalah jumlah berlian Aztec ditumpangkan ukuran ndalam struktur, seperti f(n,n) = (4*n**4-n*n-3*n)/6. f(7,3)memiliki 5 ukuran berlian Aztec3 , sementara f(3,3)hanya memiliki 1 berlian.
  • -f(m-1,n-1) menghapus beberapa duplikat persegi panjang dari tengah berlian yang dilapiskan.
  • +(m-n)*2menyumbang 2 ekstra- 2oleh-(2n-1) persegi panjang untuk setiap berlian ekstra.
  • +(m-n)*(n-2)menyumbang tambahan n-by- npersegi untuk setiap berlian ekstra.
  • -(m-n-1)*f(n-1,n-1)Ini adalah istilah baru yang membingungkan. Tampaknya saya belum menghitung beberapa kotak tambahan dalam penghitungan saya, tapi saya belum menemukan di mana mereka berada di berlian diperpanjang.

Catatan: kapan m==n,, m-n-1 = -1artinya istilah terakhir ini menambahkan kotak ke penghitungan. Saya mungkin kehilangan sesuatu dalam formula biasa saya. Pengungkapan penuh, ini hanya dimaksudkan sebagai tambalan untuk rancangan awal formula ini yang baru saja berfungsi. Jelas, saya masih perlu menggali apa yang terjadi, dan mungkin formula saya mengandung beberapa bug di dalamnya. Saya akan membuat Anda diposting.

Russell, Gary dan Weisstein, Eric W. "Aztec Diamond." Dari MathWorld - Sumber Daya Web Wolfram. http://mathworld.wolfram.com/AztecDiamond.html

Sherlock9
sumber
Saya suka bagaimana jawaban ini memiliki lebih banyak semangat daripada jawaban yang asli, dan hadiah +100 ...: P
HyperNeutrino
5

C, 71 64 byte

f(m,n){return n>m?f(n,m):m*~m*n*~n/4+n*((2*m-n)*(4*n*n-1)-3)/6;}

Cobalah di Ideone

betseg
sumber
2
Saya ingin tahu apa yang terjadi di sini dan bagaimana Anda sampai pada solusi ini.
Jordan
1
@ Jordan Sejauh ini saya telah memverifikasi bagian kedua dari rumus untuk m==n: jumlah persegi panjang miring dalam n*nkotak adalah (4*n*n*n*n-n*n-3*n)/6. Urutannya adalah 0, 9, 51, 166, 410, 855, 1589, 2716, 4356, 6645 tetapi tidak muncul di OEIS.
Neil
1
Saya sekarang telah memverifikasi bahwa ketika m>nAnda perlu menambahkan tambahan (m-n)(n*(4*n*n-1)/3)(bagian terakhir dari rumus yang diambil dari OEIS A000447). Mengatur ulang dan menambahkan memberi rumus @ betseg.
Neil
@ Neil Bagaimana Anda sampai pada formula itu?
Sherlock9
2
@ Sherlock9 Saya secara manual menghitung jumlah persegi miring dalam 10 kotak pertama dan memasukkan urutan ke mesin pencari OEIS yang tidak mengenali urutan tetapi menemukan formula untuk itu yang cocok dengan formula OP untuk m==n. Saya kemudian secara manual menghitung jumlah persegi panjang miring dalam persegi panjang kecil dan melihat peningkatan dimensi yang lebih panjang selalu menambahkan jumlah persegi panjang yang sama untuk dimensi yang diberikan lebih pendek. Saya memasukkan kenaikan ke OEIS yang menemukan kecocokan pada A000447.
Neil
4

Python, 73 68 byte

x=lambda m,n:m*~m*n*~n/4+n*((2*m-n)*(4*n*n-1)-3)/6if m>n else x(n,m)

Dan sementara versi berikut memiliki bytecount yang lebih tinggi (75), itu adalah latihan yang bagus dalam menemukan tempat untuk digunakan ~:

def f(r,c):
 if r<c:r,c=c,r
 x=(4*c**3-c)/3
 return r*c*~r*~c/4+x*r--~x*c/2
Marcus Andrews
sumber
68 byte jika Anda menggunakan lambda:x=lambda m,n:m*~m*n*~n/4+n*((2*m-n)*(4*n*n-1)-3)/6if m>n else x(n,m)
GamrCorps
Ahh, entah kenapa aku menduga kami harus menggunakannya def. Terima kasih! Diperbarui.
Marcus Andrews
3

Cembung, 37 36 byte

__:)+×½½\~æ<{\}&:N\¦\-N¦¦N*(*3-N*6/+

Cobalah online!

Menggunakan algoritma betseg yang dimodifikasi dan dioptimalkan untuk bahasa berbasis stack. Penjelasan yang akan datang ketika saya memiliki waktu luang lagi. Saya yakin ini bisa dipersingkat tapi saya tidak akan repot saat ini.

GamrCorps
sumber
2

Batch, 82 byte

@if %2 gtr %1 %0 %2 %1
@cmd/cset/a%1*~%1*%2*~%2/4+((%1+%1-%2)*(%2*%2*4-1)-3)*%2/6
Neil
sumber