Pascal's Rhombus

20

Pascal's Rhombus (yang sebenarnya adalah segitiga) diperoleh dengan menambahkan dalam pola:

  *
 ***
  x

dari pada

* *
 x

Ini berarti bahwa setiap sel adalah jumlah dari tiga sel pada baris tepat di atasnya dan satu sel pada baris 2 di atasnya. Sama seperti segitiga Pascal, baris nol memiliki satu 1di atasnya yang menghasilkan segitiga.

Inilah beberapa baris pertama Pascal's Rhombus

      1
    1 1 1
  1 2 4 2 1
1 3 8 9 8 3 1

Tugas

Diberikan nomor baris (mulai dari atas) dan nomor kolom (mulai dari item bukan nol pertama pada baris itu) menghasilkan nilai pada sel tertentu. Kedua input dapat diindeks 1 atau 0 (Anda dapat mencampur dan mencocokkan jika Anda inginkan).

Ini adalah sehingga Anda harus berusaha membuat ukuran file kode sumber Anda sekecil mungkin.

OEIS A059317

Wisaya Gandum
sumber
4
Seperti halnya segitiga Pascal, paritas belah ketupat membuat pola yang bagus dan fraktal .
Martin Ender
Anda harus bertujuan untuk membuat ukuran file kode sumber Anda sekecil mungkin bagaimana jika saya meletakkan kode saya sebagai argumen baris perintah? : P
Erik the Outgolfer
Pergi googling untuk pintasan dan rupanya arxiv.org/abs/1504.04404 mengatakan menghitung hasilnya secara langsung tidak dapat digunakan untuk kode golf.
JollyJoker

Jawaban:

12

Haskell , 59 55 byte

Belah Ketupat Pascal? Lebih seperti Haskell's Rhombus! Apakah saya benar?

4 byte disimpan berkat Ørjan Johansen

Saya pikir saya akan mencoba masalah saya sendiri dan mempraktikkan Haskell saya. Semoga ini akan menginspirasi lebih banyak orang untuk menjawab ini.

1!1=1
n!k=sum[(n-2)!(k-2)+sum(map((n-1)!)[k-2..k])|n>1]

Cobalah online!

Penjelasan

Ini agak ketinggalan zaman dengan golf terbaru

Alih-alih menghitung

  *
 ***
  x

Kami menghitung

*
***
  x

Ini miring seluruh segitiga kita untuk menjadi

1
1 1 1
1 2 4 2 1
1 3 8 9 8 3 1

Ini mengurutkan semua baris kami sehingga memudahkan untuk mengindeks item ke-n kolom mana saja. Kami kemudian mendefinisikan kasus dasar kami.

Baris nol adalah semua nol begitu

0!_=0

Ada satu 1di posisi 1,1jadi kami mendefinisikannya

1!1=1

Dan kami mendefinisikan sisa baris pertama menjadi nol juga

1!_=0

Kemudian kami mendefinisikan kasus umum secara rekursif menggunakan pola yang dijelaskan di atas:

n!k=(n-2)!(k-2)+(sum$map((n-1)!)[k-2..k])
Wisaya Gandum
sumber
Kalahkan aku! Ini juga jauh lebih bersih daripada milikku.
Julian Wolf
@JulianWolf Maaf tentang itu, ketika saya memposting ini sepertinya tidak ada yang lain selain Jorg yang melakukan masalah. Saya masih ingin melihat solusi Anda.
Wheat Wizard
1
Anda dapat menyimpan empat byte dengan n!k=sum[(n-2)!(k-2)+sum(map((n-1)!)[k-2..k])|n>1].
Ørjan Johansen
10

Pascal , 122 byte

Yah, ini adalah belah ketupat Pascal .

37 byte disimpan berkat @manatwork

function f(n,k:integer):integer;begin f:=1-Ord((k<0)or(k>n*2));if n>0then f:=f(n-1,k-2)+f(n-1,k-1)+f(n-1,k)+f(n-2,k-2)end;

Cobalah online!

Uriel
sumber
Parenthesis di sekitar seluruh ifkondisi tidak ada gunanya. (Pada tanggal 1 ifAnda menyimpan 2 karakter, pada ifkarakter 1 ke- 1 dengan tidak meninggalkan spasi antara thenkata kunci dan digit sebelumnya.) Oh, dan variabel r sama sekali tidak perlu.
manatwork
Hewan aneh yang Pascal di Ideone. Belum pernah melihat tanda kutip ganda dibatasi string dalam varian Pascal sebelumnya. Satu hal lagi yang dapat menghapus: yang ;sebelum function's end.
manatwork
@manatwork ya, sekarang ketika Anda menyebutkannya, semua editor online lainnya mengeluh tentang hal itu
Uriel
@Manatwork Saya tidak yakin saya mengerti. bukankah itu hanya memperpanjang kode dengan >= <=? Saya masih perlu melestarikanif n=0
Uriel
Maaf @Uriel, saya tidak memiliki versi itu lagi. Saat ini saya difunction f(n,k:integer):integer;begin f:=1-Ord((k<0)or(k>n*2));if n>0then f:=f(n-1,k-2)+f(n-1,k-1)+f(n-1,k)+f(n-2,k-2)end;
manatwork
7

PHP , 86 byte

cara rekursif hanya fungsi baris dan kolom 0-diindeks

function f($r,$c){return$r|$c?$r<0?0:f($r-=1,$c)+f($r,$c-1)+f($r,$c-=2)+f($r-1,$c):1;}

Cobalah online!

PHP , 114 byte

cara rekursif program baris penuh dan kolom 0-diindeks

<?=f(...$_GET);function f($r,$c){return$r|$c?$r<0|$c<0|$c>2*$r?0:f($r-=1,$c)+f($r,$c-1)+f($r,$c-=2)+f($r-1,$c):1;}

Cobalah online!

PHP , 129 byte

baris dan kolom 0-Diindeks

for(;$r<=$argv[1];$l=$t[+$r++])for($c=~0;$c++<$r*2;)$t[+$r][$c]=$r|$c?$t[$r-2][$c-2]+$l[$c]+$l[$c-1]+$l[$c-2]:1;echo$l[$argv[2]];

Cobalah online!

Jörg Hülsermann
sumber
dan +1 untuk benar-benar meningkatkannya :)
Uriel
4

Jelly , 22 20 19 byte

3ḶṚp@Ḣḣ4
Ḟ_ЀÇ߀ȯ¬S

Mengambil pasangan indeks berbasis 0 sebagai argumen baris perintah.

Cobalah online!

Dennis
sumber
3

MATL , 22 20 19 byte

Ti:"2Y6Y+FT_Y)]!i_)

Kedua input berbasis 0.

Cobalah online!

Penjelasan

Biarkan rdanc tunjukkan kedua input, dengan menentukan baris dan kolom berbasis 0 masing-masing.

Setiap baris baru dalam belah ketupat Pascal dapat dibangun dari matriks yang berisi dua baris sebelumnya dengan berbelit - belit dengan kernel [1 1 1; 0 1 0]dan menjaga dua baris terakhir dari hasil swap. Ini dilakukan rkali, mulai dari matriks 1.

Ternyata lebih pendek untuk menggunakan kernel [0 1 0; 1 1 1; 0 1 0], yang merupakan literal yang sudah ditentukan sebelumnya. Ini menghasilkan baris tambahan, yang akan dibuang.

Pertimbangkan misalnya r = 3, jadi ada 3iterasi.

  1. Mulai dari

    1
    

    konvolusi dengan [0 1 0; 1 1 1; 0 1 0]memberi

    0 1 0
    1 1 1
    0 1 0
    

    Mempertahankan dua baris terakhir (seluruh matriks, dalam kasus ini) dan menukar memberi

    0 1 0
    1 1 1
    
  2. Konvolusi di atas dengan [0 1 0; 1 1 1; 0 1 0]memberi

    0 0 1 0 0
    0 1 1 1 0
    1 2 4 2 1
    0 1 1 1 0
    

    Matriks yang dibentuk oleh dua baris terakhir ditukar adalah

    0 1 1 1 0
    1 2 4 2 1
    

    Ini berisi baris baru di bagian bawah, dan yang sebelumnya diperpanjang dengan nol.

  3. Menggabungkan lagi hasil panen

    0 0 1 1 1 0 0
    0 1 2 3 2 1 0
    1 3 8 9 8 3 1
    0 1 2 4 2 1 0
    

    Mengambil dua baris terakhir bertukar memberi

    0 1 2 4 2 1 0
    1 3 8 9 8 3 1
    

Setelah riterasi dilakukan, output terkandung di baris terakhir dari matriks final. Misalnya, untuk c = 2(berbasis 0) hasilnya akan 8. Alih-alih mengindeks baris terakhir dan kolom yang diinginkan, trik dapat digunakan yang mengeksploitasi simetri setiap baris: matriks akhir ditransformasikan

0 1
1 3
2 8
4 9
2 8
1 3
0 1

dan -celemen ke -nya diambil. Ini menggunakan pengindeksan linear, yaitu, matriks diindeks oleh indeks tunggal dalam urutan kolom-utama . Karena pengindeksan bersifat modular , entri-adalah 0sudut kanan bawah (nilai 1) dan -2entri-adalah dua langkah di atas (nilai 8).

T       % Push true
i       % Input row number
:"      % Do the following that many times
  2Y6   %   Push predefined literal [0 1 0; 1 1 1; 0 1 0]
  Y+    %   2D convolution, increasing size
  FT_   %   Push [0 -1]
  Y)    %   Matrix with rows 0 (last) and -1 (second-last), in that order
]       % End
!       % Transpose
i       % Input: colun number
_       % Negate
)       % Entry with that index. Implicitly display
Luis Mendo
sumber
3

Pari / GP , 60 byte

i->j->polcoeff(Vec(1/(1-x*(1+y+y^2+x*y^2))+O(x^i++))[i],j,y)

Cobalah online!

alephalpha
sumber
2

Haskell , 74 byte

0#0=1
n#m|m<=2*n&&m>=0=sum[(n-a)#(m-b)|(a,b)<-zip[2,1,1,1]$2:[0..2]]
n#m=0

Cobalah online!

Panggil dengan n # m, di mana nbaris dan mkolom.

Julian Wolf
sumber
m<=2*n&&m>=0bisa adil n>0.
Ørjan Johansen
2

Mathematica, 56 byte

If[#<1,Boole[##==0],Sum[#0[#-i,#2-j],{i,2},{j,2i-2,2}]]&

Fungsi murni mengambil dua argumen integer (baris pertama, kolom kedua) dan mengembalikan integer. Berfungsi untuk argumen integer negatif juga, kembali 0. Struktur rekursif yang cukup mudah: If[#<1,Boole[##==0],...]mendefinisikan perilaku kasus dasar untuk baris ke-0 (dan di atas), sementara Sum[#0[#-i,#2-j],{i,2},{j,2i-2,2}]mengimplementasikan definisi rekursif.

Greg Martin
sumber
1

JavaScript (ES6), 68 byte

f=(y,x)=>x<0|x>y+y?0:x>0&x<y+y?f(--y,x)+f(y,--x)+f(y,--x)+f(--y,x):1
Neil
sumber
1

Mathematica, 53 byte

D[1/(1-x(1+y+y^2(1+x))),{x,#},{y,#2}]/#!/#2!/.x|y->0&

Menggunakan fungsi pembangkit.

alephalpha
sumber
0

Python 3 , 82 84 byte

Ini adalah implementasi rekursif dengan baris dan kolom 1-diindeks. (Secara teknis membutuhkanf= di depan, seseorang memberi tahu saya jika saya harus mengubahnya ke 84 byte. Masih baru dan tidak 100% yakin dengan aturan.)

Ini menggunakan rumus rekursif yang ditemukan di halaman OEIS , tetapi dengan yang kbergeser ke kiri untuk berbaris dengan benar. Secara kebetulan, sum(f(n-1,k-i)for i in(0,1,2))ukurannya sama dengan f(n-1,k)+f(n-1,k-1)+f(n-1,k-2). Seluruh fungsi adalah and ortrik Python , di mana kondisi pertama memeriksa apakah k berada di dalam segitiga dan bukan pada batas, dalam hal ini rumus rekursif digunakan. Jika tidak, bagian setelah ordikembalikan, yang memeriksa jika kdalam (1, 2*n-1), yaitu pada batas, kembaliTrue dan False. k+1in(2,2*n)lebih pendek satu byte dari k in(1,2*n-1). Membungkus itu dalam tanda kurung dan meletakkan +di depan mengkonversi ke integer, yang adalah apa yang dibutuhkan.

f=lambda n,k:2*n-1>k>1and sum(f(n-1,k-i)for i in(0,1,2))+f(n-2,k-2)or+(k+1in(2,2*n))

Cobalah online!

C McAvoy
sumber
Fungsi rekursif membutuhkan f=.
Wheat Wizard
Sementara saya pribadi tidak setuju dengan itu menurut ini meta konsensus agak terkubur, Anda mungkin keluaran Truebukan 1karena berperilaku seperti 1untuk python. Ini memungkinkan Anda untuk menghapus +(...)di akhir. Saya mengerti jika Anda tidak ingin melakukan ini, karena itu akan membuat output terlihat sedikit aneh, itu adalah pilihan.
Wheat Wizard
@WheatWizard Wow itu sangat menarik. Terima kasih atas tipnya.
C McAvoy
0

Java (OpenJDK 8) , 87 byte

int f(int r,int c){return c<0|2*r<c?0:0<c&c<2*r?f(--r,c)+f(r,--c)+f(r,--c)+f(--r,c):1;}

Cobalah online!

Pada awalnya, saya senang dengan metode iteratif 160 byte saya ... Hmmm ... mari kita lupakan saja, oke?

Olivier Grégoire
sumber
0

Python 3 , 75 Bytes

Ini adalah lambda rekursif yang mengambil kolom dan baris sebagai bilangan bulat berindeks 0.

p=lambda r,c:(r<0 or((c==0)|p(r-1,c-2)+p(r-1,c)+p(r-1,c-1)+p(r-2,c-2))+1)-1

Berikut ini (versi) yang lebih mudah dibaca dengan fungsi pencetakan:

p = lambda r,c:(r<0 or ((c==0) | p(r-1,c-2)+p(r-1,c)+p(r-1,c-1)+p(r-2,c-2))+1)-1

def pp(r):
    ml = len(str(p(r,r)))+1
    for i in range(0, r):
            a=" "*ml*(r-i)
            for j in range(0,i*2 + 1):
                    a+=str(p(i,j))+(" "*(ml-len(str(p(i,j)))))
            print(a)
Eric Canam
sumber