Contando fuentes


17

Una fuente es una disposición de monedas en filas para que cada moneda toque dos monedas en la fila debajo de ella, o esté en la fila inferior, y la fila inferior esté conectada. Aquí hay una fuente de 21 monedas:

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


Su desafío es contar cuántas fuentes diferentes se pueden hacer con un número determinado de monedas.

Se le dará como entrada un número entero positivo n. Debe generar la cantidad de nfuentes de monedas diferentes que existen.

Reglas estándar de E / S, lagunas estándar prohibidas. Las soluciones deberían poder calcularse n = 10en menos de un minuto.


Salida deseada para n = 1 ... 10:

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

Esta secuencia es OEIS A005169 .


Este es el código de golf. Pocos bytes ganan.


¿Existe alguna npara la cual se debe garantizar que el programa funcione? (es decir, después de lo cual puede romperse)
quintopia

@quintopia Debería funcionar para todos n, hasta limitaciones de tipo de datos, hardware, etc.
isaacg

Respuestas:


3

Python, 57 bytes

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

Como se observa en OEIS , si desplaza cada fila medio paso en relación con la fila debajo de ella, los tamaños de columna forman una secuencia de enteros positivos con un paso ascendente máximo de 1.

La función f(n,i)cuenta las secuencias con suma ny último número i. Estos se pueden sumar recursivamente para cada elección del siguiente tamaño de columna de 1a i+1, que es range(1,i+2). Truncar para range(1,i+2)[:n]evitar que las columnas usen más monedas de las que quedan, evitando tener que decir que los negativos ndan 0. Además, evita un caso base explícito, ya que la suma vacía es 0y no es recurrente, pero f(0)debe establecerse en su 1lugar, para lo cual es or 1suficiente (como lo haría +0**n).


17 bytes en Pyth:M|sgL-Gd<ShHG1gQ0
isaacg

5

Mathematica, 59 bytes

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

Basado en el programa Mathematica en OEIS de Jean-François Alcover.


¿Puedes reescribir esto como una fórmula (solo quiero comparar con la fórmula que encontré)? Simplemente no puedo leer Mathematica =)
flawr

@flawr La función generadora de la secuencia es 1/(1-x/(1-x^2/(1-x^3/(1-x^4/(1-x^5/(...)))))).
alephalpha

Gracias por la explicación, que es de hecho un acercamiento agradable si usted tiene un potente CAS =) tal
flawr

3

Haskell 60 48 bytes

¡Gracias a @nimi por proporcionar una solución mucho más corta!

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

Versión antigua.

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 función que calcula el valor es la simplementación de la fórmula recursiva que se encuentra aquí: https://oeis.org/A005169


Un error: la llamada recursiva es t (n-p) q. Golf en las extremidades: utilizar un operador infijo para t, intercambiar los guardias y utilizar mapen lugar de la lista por comprensión: n#p|p>n=0|p<n=sum$map((n-p)#)[1..p+1]|1<2=1. sse convierte s=(#1), pero no es necesario que le dé un nombre a la función principal, por lo que (#1)es suficiente. 48 bytes.
nimi

Muchas gracias por las pistas! Acabo de empezar a aprender los conceptos básicos de Haskell. Voy a tener que aprender sobre cómo el uso de #y $aquí primero =)
error

Un poco de explicación: #es una función infija definida por el usuario como +, *, etc., están funciones predefinidas infijos. $es otra forma de ajustar la precedencia (además de paréntesis) f (g (h x))-> f$g$h xo en nuestro caso sum(map(...)[...])-> sum$map(...)[...].
nimi

Gracias, es bastante útil saberlo, ¡agradezco su explicación!
flawr

3

Haskell, 43 bytes

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

Ver la respuesta de Python para obtener una explicación.

Misma longitud con minmás que take:

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


1

Matlab, 115105 bytes

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

Implementación de la fórmula recursiva que se encuentra aquí: 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 bytes

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

Esto utiliza la fórmula recursiva en OEIS.

Explicación

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

¿Alguien más se ha dado cuenta de que el strike 44 es regular 44?


0

Python 3, 88 bytes

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

Implementando la fórmula recursiva en la página OEIS

F=(n,p=1,t=0,q=0)=>p<n?eval("for(;q++<=p;)t+=F(n-p,q)"):p>n?0:1
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.