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



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

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!


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!


dan +1 untuk benar-benar meningkatkannya :)
Uriel


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



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.



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

1

Mathematica, 53 byte

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

Menggunakan fungsi pembangkit.


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!


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

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