Виведіть n-й номер дзвоника


13

Номер дзвоника ( OEIS A000110 ) - це кількість способів розділити набір з n мічених (різних) елементів. Номер 0-го дзвоника визначається як 1.

Давайте розглянемо кілька прикладів (я використовую дужки для позначення підмножин та дужок для розділів):

1: {1}
2: {[1,2]}, {[1],[2]}
3: {[1,2,3]}, {[1,2],[3]}, {[1,3],[2]}, {[2,3],[1]}, {[1],[2],[3]}

Існує багато способів обчислити числа Белла, і ви можете вільно користуватися будь-яким з них. Тут буде описано один із способів:

Найпростіший спосіб обчислити числа Белла - використовувати трикутник чисел, що нагадує трикутник Паскаля для двочленних коефіцієнтів. Номери Дзвона з’являються на краях трикутника. Починаючи з 1, кожен новий рядок у трикутнику будується, приймаючи останній запис у попередньому рядку як перший запис, а потім встановлюючи кожен новий запис лівому сусіду плюс верхньому лівому сусіду:

1
1    2
2    3    5
5    7   10   15
15  20   27   37   52

Ви можете використовувати 0-індексацію або 1-індексацію. Якщо ви використовуєте 0-індексацію, вхід 3повинен виводити 5, але повинен виводити, 2якщо ви використовуєте 1-індексацію.

Ваша програма повинна працювати до 15-го номера дзвоника, виводячи 1382958545. Теоретично ваша програма повинна вміти обробляти більшу кількість (іншими словами, не жорстко кодуйте рішення). EDIT: Вам не потрібно обробляти введення 0 (для 0-індексації) або 1 (для 1-індексації), оскільки це не обчислюється методом трикутника.

Тестові приклади (припускаючи 0-індексацію):

0 ->  1 (OPTIONAL)
1 ->  1 
2 ->  2 
3 ->  5 
4 ->  15 
5 ->  52 
6 ->  203 
7 ->  877 
8 ->  4140 
9 ->  21147 
10 -> 115975 
11 -> 678570 
12 -> 4213597 
13 -> 27644437 
14 -> 190899322 
15 -> 1382958545

Відповіді за допомогою вбудованого методу (наприклад, BellB [n] у мові Wolfram), який безпосередньо створює номери Белла, будуть неконкурентоспроможними.

Найкоротший код (у байтах) виграє.


Якщо ви використовуєте 0-індексацію, вхід 3повинен виводити5 це буде вичерпано 15, чи не так? І при 1-індексації це вийде5
Луїс Мендо

Обґрунтуванням цього вважалося число 0-го дзвоника як індекс 0 в 0-індексації та індекс 1 в 1-індексації. Ваш спосіб може бути більш зрозумілим, але існуючі відповіді працюють так, тому я зараз не можу його змінити. Я щойно приєднався до цього сайту кілька годин тому
сфальсифікований

Але ви кажете, що при 1-індексації вхід 3повинен виводити 2. Тоді що введення 1дасть при 1-індексації?
Луїс Мендо

1 -> 1, 2 -> 1, 3 -> 2 (відповідає номерам 0-го, 1-го та 2-го дзвонів) на відміну від 0 -> 1, 1 -> 1, 2 -> 2 Можливо, я використовую неправильну термінологія
сфальсифікований

Я думаю, що я це розумію. Перший 1 відсутній у вашій прикладі таблиці та результатів, що мене бентежило
Луїс Мендо

Відповіді:


2

Желе , 9 байт

ṖµṀcæ.߀‘

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

формула

який закривається щоразу, коли n <2 .

Спробуйте в Інтернеті!

Як це працює

ṖµṀcæ.߀‘  Main link. Argument: n

Ṗ          Pop; yield A := [1, ..., n-1].
 µ         Begin a new, monadic chain with argument A.
  Ṁ        Maximum; yield n-1.
   c       Combinatons; compute (n-1)C(k) for each k in A.
      ߀   Recursively map the main link over A.
    æ.     Take the dot product of the results to both sides.
        ‘  Increment; add 1 to the result.

8

JavaScript (ES6), 47 байт

f=(n,a=[b=1])=>n--?f(n,[b,...a.map(e=>b+=e)]):b
f=(n,a=[b=1])=>--n?f(n,[b,...a.map(e=>b+=e)]):b

Перший - 0-індексований, другий - 1-індексований.





3

Желе , 14 12 11 байт

ṫ0;⁸+\
1Ç¡Ḣ

Спробуйте в Інтернеті!

Не точно вдарив по сильних точках Jelly з динамічним входом до ¡, завжди змінюючи масив і відсутність атома, що готується, (однобайтовий ;@або зворотний ).



3

MATL , 14 байт

:dtEw1Zh1Ze/Yo

Введення на основі 0. Спробуйте в Інтернеті!

Пояснення

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

введіть тут опис зображення

де p F q ( a 1 , ..., a p ; b 1 , ..., b q ; x ) - узагальнена гіпергеометрична функція .

:      % Implictly input n. Push array [1 2 ... n]
d      % Consecutive differences: array [1 ... 1] (n-1 entries)
tE     % Duplicate, multiply by 2: array [2 ... 2] (n-1 entries)
w      % Swap
1      % Push 1
Zh     % Hypergeometric function
1Ze    % Push number e
/      % Divide
Yo     % Round (to prevent numerical precision issues). Implicitly display

3

Пітон , 42 байти

f=lambda n,k=0:n<1or k*f(n-1,k)+f(n-1,k+1)

Спробуйте в Інтернеті!

Рекурсивна формула походить від розміщення nелементів у розділах. Для кожного елемента по черзі ми вирішуємо, чи розміщувати його:

  • У існуючий розділ, з якого є kвибір
  • Запустити новий розділ, який збільшує кількість варіантів kдля майбутніх елементів

У будь-якому випадку зменшується кількість nінших елементів, які потрібно розмістити. Отже, у нас є рекурсивна формула f(n,k)=k*f(n-1,k)+f(n-1,k+1)і f(0,k)=1, з f(n,0)n-го числа Белла.


2

Python 2 , 91 байт

s=lambda n,k:n*k and k*s(n-1,k)+s(n-1,k-1)or n==k
B=lambda n:sum(s(n,k)for k in range(n+1))

Спробуйте в Інтернеті!

B (n) обчислюється як сума чисел Стірлінга другого роду.


Це приємне рішення. Зауважте, що використання вбудованих для чисел Стірлінга другого роду дозволить обчислити числа Белла (якщо використовується Mathematica чи подібні)
сфальсифікований

Ви можете зберегти два байти безпосередньо у визначенні s: оскільки рекурсивні дзвінки завжди зменшуються, nі поділу на них немає, kви можете втратити *kперший раз.
Пітер Тейлор

Або ви можете зберегти купу, сплюснувши в одну лямбду, працюючи цілими рядами:B=lambda n,r=[1,0]:n and B(n-1,[k*r[k]+r[k-1]for k in range(len(r))]+[0])or sum(r)
Пітер Тейлор

оскільки ваша функція Bне є рекурсивною, і це ваша остаточна відповідь, ви можете опустити, B=щоб зберегти 2 байти
Феліпе Нарді Батіста

2

MATLAB, 128 103 байт

function q(z)
r(1,1)=1;for x=2:z
r(x,1)=r(x-1,x-1);for y=2:x
r(x,y)=r(x,y-1)+r(x-1,y-1);end
end
r(z,z)

Досить пояснюючи себе. Опущення крапки з комою в кінці рядка друкує результат.

25 байт збережено завдяки Луїсу Мендо.




2

Ом , 15 байт

2°M^┼ⁿ^!/Σ;αê/≈

Спробуйте в Інтернеті!

Використовує форуми Добінського (навіть працює для B (0) yay ).

Пояснення

2°M^┼ⁿ^!/Σ;αê/≈
2°        ;     # Push 100
  M             # Do 100 times...
   ^             # Push index of current iteration
    ┼ⁿ           # Take that to the power of the user input
      ^!         # Push index factorial
        /        # Divide
         Σ       # Sum stack together
           αê   # Push e (2.718...)
             /  # Divide
              ≈ # Round to nearest integer (Srsly why doesn't 05AB1E have this???)

2

Пітон (79 байт)

B=lambda n,r=[1]:n and B(n-1,[r[-1]+sum(r[:i])for i in range(len(r)+1)])or r[0]

Демонстрація в Інтернеті в Python 2, але вона також працює в Python 3.

Це будує трикутник Ейткена, використовуючи рекурсивну лямбда для гофрованого циклу.



1

J, 17 байт

0{]_1&({+/\@,])1:

Використовується метод обчислення трикутника.

Спробуйте в Інтернеті!

Пояснення

0{]_1&({+/\@,])1:  Input: integer n
               1:  The constant 1
  ]                Identity function, get n
   _1&(       )    Call this verb with a fixed left argument of -1 n times
                   on itself starting with a right argument [1]
             ]       Get right argument
       {             Select at index -1 (the last item)
            ,        Join
        +/\@         Find the cumulative sums
0{                 Select at index 0 (the first item)

1

Python 3 , 78 байт

from math import*
f=lambda n:ceil(sum(k**n/e/factorial(k)for k in range(2*n)))

Я вирішив спробувати і піти іншим маршрутом для розрахунку. Тут використовується формула Добінського, 0-індексована, не працює для 0.

Спробуйте в Інтернеті!


1
оскільки ваша функція fне є рекурсивною, ви можете опустити f=і зберегти 2 байти
Felipe Nardi Batista

1

Python 3 , 68 60 байт

Проста рекурсивна побудова трикутника, але дико неефективна для практичних цілей. Обчислення до 15-го числа Белла спричиняє час TIO, але він працює на моїй машині.

При цьому використовується 1-індексація, а повертається Trueзамість 1.

f=lambda r,c=0:r<1or c<1and f(r-1,r-1)or f(r-1,c-1)+f(r,c-1)

Спробуйте в Інтернеті!


Дякуємо @FelipeNardiBatista за збереження 8 байт!


60 байт . повернення буленів замість чисел (0,1) допустимо в пітоні
Феліпе Нарді Батіста

1

PHP , 72 байти

рекурсивна функція 1-індексована

function f($r,$c=0){return$r?$c?f($r-1,$c-1)+f($r,$c-1):f($r-1,$r-2):1;}

Спробуйте в Інтернеті!

PHP , 86 байт

0-індексований

for(;$r++<$argn;)for($c=~0;++$c<$r;)$l=$t[$r][$c]=$c?$l+$t[$r-1][$c-1]:($l?:1);echo$l;

Спробуйте в Інтернеті!

PHP , 89 байт

рекурсивна функція 0-індексується

function f($r,$s=NULL){$c=$s??$r-1;return$r>1?$c?f($r-1,$c-1)+f($r,$c-1):f($r-1,$r-2):1;}

Спробуйте в Інтернеті!


1

Аліса , 22 байти

/oi
\1@/t&wq]&w.q,+k2:

Спробуйте в Інтернеті!

Для цього використовується метод трикутника. Для n = 0 замість цього обчислюється B (1), що зручно рівним B (0).

Пояснення

Це стандартний шаблон для програм, які приймають введення в порядковому режимі, обробляють його в кардинальному режимі і виводять результат у порядковий режим. 1До шаблону додано " A ", щоб поставити це значення на стек нижче введення.

Програма використовує стек як розширюється кругова черга для обчислення кожного ряду трикутника. Під час кожної ітерації минулого першого один неявний нуль під стеком стає явним нулем.

1     Append 1 to the implicit empty string on top of the stack
i     Get input n
t&w   Repeat outer loop that many times (push return address n-1 times)
q     Get tape position (initially zero)
]     Move right on tape
&w    On iteration k, push this return address k-1 times
      The following inner loop is run once for each entry in the next row
.     Duplicate top of stack (the last number calculated so far)
q,    Move the entry k spaces down to the top of the stack: this is the appropriate entry
      in the previous row, or (usually) an implicit zero if we're in the first column
+     Add these two numbers
k     Return to pushed address: this statement serves as the end of two loops simultaneously
2:    Divide by two: see below
o     Output as string
@     Terminate

Перша ітерація ефективно передбачає початкову глибину стека нуля, незважаючи на необхідну 1 у верхній частині стека. Як результат, 1 закінчується додаванням до себе, а весь трикутник множиться на 2. Ділення кінцевого результату на 2 дає правильну відповідь.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.