Menghitung Air Mancur

17

Sebuah air mancur adalah susunan koin di baris sehingga setiap koin menyentuh dua koin berturut-turut di bawahnya, atau di baris bawah, dan baris bawah terhubung. Inilah air mancur 21 koin:

Dari http://mathworld.wolfram.com/Fountain.html


Tantangan Anda adalah menghitung berapa banyak air mancur yang berbeda dapat dibuat dengan jumlah koin tertentu.

Anda akan diberikan sebagai input bilangan bulat positif n. Anda harus menampilkan jumlah nair mancur -coin berbeda yang ada.

Aturan I / O standar, celah standar dilarang. Solusi harus dapat dihitung n = 10dalam waktu kurang dari satu menit.


Output yang diinginkan untuk n = 1 ... 10:

1, 1, 2, 3, 5, 9, 15, 26, 45, 78

Urutan ini adalah OEIS A005169 .


Ini kode golf. Bytes paling sedikit menang.

isaacg
sumber
Apakah ada nprogram yang harus dijamin berfungsi? (Yaitu setelah itu mungkin pecah)
kuintopia
@quintopia Ini harus bekerja untuk semua n, hingga batasan tipe data, perangkat keras, dll.
isaacg

Jawaban:

3

Python, 57 byte

f=lambda n,i=0:sum(f(n-j,j)for j in range(1,i+2)[:n])or 1

Seperti yang diamati pada OEIS , jika Anda menggeser setiap baris setengah langkah relatif terhadap baris di bawahnya, ukuran kolom membentuk urutan bilangan bulat positif dengan langkah ke atas maksimum 1.

Fungsi f(n,i)menghitung urutan dengan jumlah ndan nomor terakhir i. Ini dapat diringkas secara rekursif untuk setiap pilihan ukuran kolom berikutnya dari 1hingga i+1, yaitu range(1,i+2). Truncating untuk range(1,i+2)[:n]mencegah kolom menggunakan lebih banyak koin dari tetap, menghindari perlu untuk mengatakan negatif yang n's memberi 0. Selain itu, ia menghindari kasus dasar eksplisit, karena jumlah kosong adalah 0dan tidak berulang, tetapi f(0)perlu diatur untuk 1sebagai gantinya, yang or 1mencukupi (seperti yang akan terjadi +0**n).

Tidak
sumber
17 byte dalam Pyth:M|sgL-Gd<ShHG1gQ0
isaacg
5

Mathematica, 59 byte

SeriesCoefficient[1-Fold[1-x^#2/#&,Range[#,0,-1]],{x,0,#}]&

Berdasarkan pada program Mathematica pada OEIS oleh Jean-François Alcover.

alephalpha
sumber
Bisakah Anda menulis ulang ini sebagai formula (saya hanya ingin membandingkan dengan formula yang saya temukan)? Saya tidak bisa membaca Mathematica =)
flawr
@ flawr Fungsi pembangkit urutan adalah 1/(1-x/(1-x^2/(1-x^3/(1-x^4/(1-x^5/(...)))))).
alephalpha
Terima kasih atas penjelasannya, itu memang pendekatan yang bagus jika Anda memiliki CAS yang kuat =)
flawr
3

Haskell, 60 48 byte

Terima kasih kepada @nimi karena menyediakan solusi yang jauh lebih singkat!

n#p|p>n=0|p<n=sum$map((n-p)#)[1..p+1]|1<2=1
(#1)

Versi lama.

t n p|p>n=0|p==n=1|p<n=sum[t (n-q) q|q<-[1..p+1]]
s n=t n 1

Fungsi yang menghitung nilainya adalah s, penerapan rumus rekursif yang ditemukan di sini: https://oeis.org/A005169

cacat
sumber
Bug: panggilan rekursif t (n-p) q. Golf tips: menggunakan operator infiks untuk t, menukar penjaga dan menggunakan mapbukannya daftar pemahaman: n#p|p>n=0|p<n=sum$map((n-p)#)[1..p+1]|1<2=1. smenjadi s=(#1), tetapi Anda tidak harus memberikan fungsi utama nama sama sekali, jadi (#1)sudah cukup. 48 byte
nimi
Terima kasih banyak atas petunjuknya! Saya baru saja mulai mempelajari dasar-dasar Haskell. Saya harus belajar tentang itu bagaimana penggunaan #dan di $sini pertama =)
flawr
Sedikit penjelasan: #adalah pengguna didefinisikan fungsi infiks seperti +, *, dll yang telah ditetapkan fungsi infiks. $adalah cara lain untuk menyesuaikan prioritas (selain tanda kurung) f (g (h x))-> f$g$h xatau dalam kasus kami sum(map(...)[...])-> sum$map(...)[...].
nimi
Terima kasih, itu cukup berguna untuk mengetahui, saya menghargai penjelasan Anda!
flawr
3

Haskell, 43 byte

n%i=sum[(n-j)%j|j<-take n[1..i+1]]+0^n
(%0)

Lihat jawaban Python untuk penjelasan.

Panjang yang sama dengan minalih - alih take:

n%i=sum[(n-j)%j|j<-[1..min(i+1)n]]+0^n
(%0)
Tidak
sumber
1

Matlab, 115 105 byte

function F=t(n,varargin);p=1;if nargin>1;p=varargin{1};end;F=p==n;if p<n;for q=1:p+1;F=F+t(n-p,q);end;end

Implementasi formula rekursif ditemukan di sini: https://oeis.org/A005169

function F=t(n,varargin);
p=1;
if nargin>1
    p=varargin{1};
end;
F=p==n;
if p<n;
    for q=1:p+1;
        F=F+t(n-p,q);
    end;
end;
cacat
sumber
1

Julia, 44 43 byte

f(a,b=1)=a>b?sum(i->f(a-b,i),1:b+1):1(a==b)

Ini menggunakan rumus rekursif pada OEIS.

Penjelasan

function f(a, b=1)
    if a > b
        # Sum of recursing
        sum(i -> f(a-b, i), 1:b+1)
    else
        # Convert bool to integer
        1 * (a == b)
    end
end

Adakah yang memperhatikan bahwa pemogokan melalui 44 adalah hal biasa?

Mesin fax
sumber
0

Python 3, 88 byte

f=lambda n,p:sum([f(n-p,q)for q in range(1,p+2)])if p<n else int(p==n)
t=lambda n:f(n,1)
satu-satunya
sumber
0

JavaScript (ES6), 63

Menerapkan rumus rekursif di halaman OEIS

F=(n,p=1,t=0,q=0)=>p<n?eval("for(;q++<=p;)t+=F(n-p,q)"):p>n?0:1
edc65
sumber