Conteggio delle fontane


17

Una fontana è una disposizione di monete in file in modo tale che ciascuna moneta tocchi due monete nella riga sottostante o sia nella riga inferiore e la riga inferiore sia collegata. Ecco una fontana con 21 monete:

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


La tua sfida è quella di contare quante diverse fontane possono essere realizzate con un determinato numero di monete.

Ti verrà dato come input un numero intero positivo n. È necessario emettere il numero di nfontane a monete diverse esistenti.

Regole I / O standard, scappatoie standard vietate. Le soluzioni dovrebbero essere in grado di calcolare n = 10in meno di un minuto.


Uscita desiderata per n = 1 ... 10:

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

Questa sequenza è OEIS A005169 .


Questo è il codice golf. Vince il minor numero di byte.


Esiste un nprogramma per cui deve essere garantito il funzionamento del programma? (cioè dopo il quale potrebbe rompersi)
quintopia il

@quintopia Dovrebbe funzionare per tutti n, fino alle limitazioni di tipo di dati, hardware, ecc.
isaacg,

Risposte:


3

Python, 57 byte

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

Come osservato su OEIS , se si sposta ogni riga di mezzo passo rispetto alla riga sottostante, le dimensioni della colonna formano una sequenza di numeri interi positivi con un passo massimo verso l'alto di 1.

La funzione f(n,i)conta le sequenze con la somma ne l'ultimo numero i. Questi possono essere sommati ricorsivamente per ogni scelta della dimensione della colonna successiva da 1a i+1, che è range(1,i+2). Troncare per range(1,i+2)[:n]impedire alle colonne di usare più monete di quante ne rimangano, evitando di dover dire che nil danno è negativo 0. Inoltre, evita un caso base esplicito, poiché la somma vuota è 0e non si basa, ma f(0)deve essere impostata su 1invece, per cui è or 1sufficiente (come farebbe +0**n).


17 byte in Pyth:M|sgL-Gd<ShHG1gQ0
isaacg il

5

Mathematica, 59 byte

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

Basato sul programma Mathematica su OEIS di Jean-François Alcover.


Puoi riscriverlo come una formula (voglio solo confrontare con la formula che ho trovato)? Non riesco proprio a leggere Mathematica =)
flawr il

@flawr La funzione generatrice della sequenza è 1/(1-x/(1-x^2/(1-x^3/(1-x^4/(1-x^5/(...)))))).
alephalpha,

Grazie per la spiegazione, questo è davvero un buon approccio se hai un CAS così potente =)
flawr il

3

Haskell, 60 anni 48 byte

Grazie a @nimi per aver fornito una soluzione più breve!

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

Vecchia versione.

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

La funzione che calcola il valore è s , implementazione della formula ricorsiva trovata qui: https://oeis.org/A005169


Un bug: la chiamata ricorsiva è t (n-p) q. Golf suggerimenti: utilizzare un operatore infisso per t, scambiare le guardie e utilizzare mapal posto della lista di comprensione: n#p|p>n=0|p<n=sum$map((n-p)#)[1..p+1]|1<2=1. sdiventa s=(#1), ma non è necessario assegnare un nome alla funzione principale, quindi (#1)è sufficiente. 48 byte.
nimi,

Grazie mille per i suggerimenti! Ho appena iniziato a studiare le basi di Haskell. Dovrò imparare a proposito di come l'utilizzo di #e $qui prima =)
flawr

Un po 'di spiegazione: #è una funzione infix definita dall'utente proprio come +,* ecc sono funzioni predefinite infissa. $è un altro modo per regolare la precedenza (oltre alle parentesi) f (g (h x))-> f$g$h xo nel nostro caso sum(map(...)[...])-> sum$map(...)[...].
nimi,

Grazie, è molto utile sapere, apprezzo la tua spiegazione!
Flawr,

3

Haskell, 43 byte

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

Vedi la risposta di Python per una spiegazione.

Stessa lunghezza con minanziché 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

Implementazione della formula ricorsiva trovata qui: 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)

Questo utilizza una formula ricorsiva su OEIS.

Spiegazione

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

Qualcun altro ha notato che lo sciopero attraverso 44 è regolare 44 ??


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

Implementazione della formula ricorsiva nella pagina OEIS

F=(n,p=1,t=0,q=0)=>p<n?eval("for(;q++<=p;)t+=F(n-p,q)"):p>n?0:1
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.