Підрахунок фонтанів


17

Фонтан є розташування монет в рядках , так що кожна монета стосується двох монет в рядку нижче її, або перебуває в нижньому ряду, а нижній ряд з'єднаний. Ось фонтан з 21 монетою:

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


Ваше завдання - порахувати, скільки різних фонтанів можна зробити з заданою кількістю монет.

Вам буде введено як вхідне додатне ціле число n. Ви повинні вивести кількість різних nфонтанів -coin, які існують.

Стандартні правила вводу / виводу, стандартні лазівки заборонені. Рішення повинні бути в змозі обчислити n = 10менше ніж за хвилину.


Бажаний вихід для n = 1 ... 10:

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

Ця послідовність є OEIS A005169 .


Це код гольфу. Виграє найменше байт.


Чи існує програма, nдля якої програма повинна гарантовано працювати? (тобто після чого вона може зламатися)
кінтопія

@quintopia Це повинно працювати для всіх n, аж до обмежень типу даних, апаратних засобів тощо
isaacg

Відповіді:


3

Пітон, 57 байт

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

Як спостерігається в OEIS , якщо змістити кожен рядок на півкроку відносно рядка під ним, розміри стовпців утворюють послідовність додатних цілих чисел з максимальним кроком вгору на 1.

Функція f(n,i)рахує послідовності з сумою nта останнім числом i. Вони можуть бути рекурсивно підсумовуються для кожного вибору наступного розміру стовпця від 1до i+1, який є range(1,i+2). Обрізання для range(1,i+2)[:n]запобігання використання стовпчиків більше монет, ніж залишається, уникаючи необхідності говорити про негативну nдачу 0. Більше того, це дозволяє уникнути явного базового випадку, оскільки порожня сума є 0і не повторюється, а f(0)повинна бути встановлена 1натомість, для чого or 1достатньо (як би +0**n).


17 байт у Pyth:M|sgL-Gd<ShHG1gQ0
isaacg

5

Математика, 59 байт

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

На основі програми Mathematica на OEIS Жана-Франсуа Алковера.


Чи можете ви переписати це як формулу (я просто хочу порівняти з знайденою формулою)? Я просто не можу прочитати Mathematica =)
недолік

@flawr Функцією, що генерує послідовність, є 1/(1-x/(1-x^2/(1-x^3/(1-x^4/(1-x^5/(...)))))).
алефальфа

Дякую за пояснення, що це справді приємний підхід, якщо у вас є такий потужний CAS =)
недолік

3

Haskell, 60 48 байт

Дякуємо @nimi за надання коротшого рішення!

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

Стара версія.

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

Функція, що обчислює значення, - sреалізація рекурсивної формули, знайденої тут: https://oeis.org/A005169


Помилка: рекурсивний дзвінок t (n-p) q. Гра в гольф поради: використовуйте оператор інфіксне для tзмініть охоронців і використовувати mapзамість списку розуміння: n#p|p>n=0|p<n=sum$map((n-p)#)[1..p+1]|1<2=1. sстає s=(#1), але вам взагалі не потрібно давати ім'я головній функції, цього (#1)достатньо. 48 байт.
німі

Дуже дякую за підказки! Я тільки почав вивчати основи Хаскелла. Мені доведеться дізнатися про те, як використання #та $тут спочатку =)
недолік

Трохи пояснення: #чи визначена користувачем функція інфікування так само +, як *і т.д., є попередньо визначеними функціями інфіксації. $є ще одним способом коригування пріоритетності (крім дужок) f (g (h x))-> f$g$h xабо в нашому випадку sum(map(...)[...])-> sum$map(...)[...].
німі

Дякую, що це цілком корисно знати, я ціную ваше пояснення!
недолік

3

Haskell, 43 байти

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

Див. Відповідь Python для пояснення.

Однакова довжина, minа не take:

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


1

Матлаб, 115 105 байт

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

Впровадження рекурсивної формули, знайденої тут: 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

Юлія, 44 43 байти

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

Для цього використовується рекурсивна формула на OEIS.

Пояснення

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

Хтось ще помітив, що страйк через 44 регулярний 44 ??



0

JavaScript (ES6), 63

Впровадження рекурсивної формули на сторінці OEIS

F=(n,p=1,t=0,q=0)=>p<n?eval("for(;q++<=p;)t+=F(n-p,q)"):p>n?0:1
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.