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.


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


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.


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


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)


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;

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?


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)

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