Числа Моцкіна


30

N-е число Моцкіна - це кількість шляхів від (0, 0) до (n, 0), де кожен крок має вигляд (1, -1), (1, 0) або (1, 1), і шлях ніколи не опускається нижче y = 0.

Ось ілюстрація цих контурів для n = 1, 2, 3, 4, з наведеного вище посилання:

Числа Моцкіна

Бажана послідовність - OEIS A001006 . OEIS має деякі інші характеристики послідовності.


Вам буде дано додатне ціле число n як вхідне. Вам слід вивести n-е число Моцкіна.

Ось цифри Моцкіна від 1 до 10:

1, 2, 4, 9, 21, 51, 127, 323, 835, 2188

Дозволені всі стандартні методи введення та виводу. Застосовуються стандартні лазівки .

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


Який мінімальний набір номерів Моцкіна ми повинні мати можливість генерувати?
Аддісон Кримп


@FlagAsSpam Усі вони, до обмеження часу / пам'яті / типу даних.
isaacg

Я думаю, що мовам потрібні слова Dyck, вбудовані зараз.
ліртосіаст

Відповіді:


15

MATL , 13 14 байт

i-2/t.5+hH4Zh

Приклад:

>> matl i-2/t.5+hH4Zh
> 6
51

EDIT (16 червня 2017 р.): Ви можете спробувати в Інтернеті! Зауважимо також, що в сучасних версіях мови (яка поставила перед цим викликом) це iможна усунути.

Пояснення

Досить просто, використовуючи еквівалентність (див. Рівняння (10)) з гіпергеометричною функцією :

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

З визначення гіпергеометричної функції

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

Зрозуміло, що порядок перших двох аргументів можна міняти, що економить один байт.

i         % input                                                   
-2/       % divide by -2
t.5+      % duplicate and add 0.5
h         % horizontal concatenation into a vector                               
H         % number 2
4         % number literal                                          
Zh        % hypergeometric function with three inputs (first input is a vector)

1
Ця відповідь прив’язана до найкоротших, а до старших приблизно на півтори години, тому я приймаю її.
isaacg

Спасибі! Я навряд чи міг уявити, що MATL навіть буде пов'язаний з Pyth. Це така важка мова, щоб перемогти її, добре розробивши її!
Луїс Мендо

11

Сітківка , 59 58 байт

+`(\D*)1(1*)
:$1<$2:$1>$2:$1_$2:
:(_|()<|(?<-2>)>)+:(?!\2)

Вводиться в одинарному режимі . Введення 7 (тобто 1111111) займає досить багато часу, але все-таки закінчується менше ніж за хвилину. Я б не пішов набагато далі від цього.

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

Пояснення

Різна характеристика чисел Моцкіна - це кількість рядків трьох різних символів, де два з них правильно врівноважені (отже, тісне відношення до каталонських чисел, які однакові без третього символу, незалежного від балансування).

Балансувальні групи .NET є досить добре розпізнають правильно підібрані рядки, так що ми просто генерувати все рядки довжини N( з використанням _, <а >також трьох символів) , а потім ми розраховуємо , скільки з них правильно збалансовані. Наприклад, для N = 4дійсних рядків:

____
__<>
_<_>
_<>_
<__>
<_>_
<>__
<<>>
<><>

Порівняно з визначенням у виклику, _відповідає (1,0)кроку, <до (1,1)та >до (1,-1).

Що стосується власне коду, то :використовується як роздільник між різними рядками. Другий регулярний вираз - це просто гольф-форма стандартного .NET-регулярного виразів для збалансованих рядків .

Що слід зауважити, це те, що :на кожному кроці між рядками є лише один вставлений між собою рядків, але другий регулярний виразок відповідає ведучому та трейлінгу :(а оскільки збіги не можуть перетинатися, це означає, що сусідні рядки, сформовані з одного шаблону на останньому кроці, не можуть обидва збігатися ). Однак це не проблема, адже щонайменше один із цих трьох може колись відповідати:

  • Якщо рядок, що закінчується на _збігах, префікс без цього _вже правильно врівноважений, <або >викине цей баланс.
  • Якщо рядок, що закінчується на >збігах, рядок врівноважується з цим >, тому _або <викине цей баланс.
  • Рядки, що закінчуються, <ніколи не можуть бути врівноваженими.

Прикро, що "\" має особливе значення, інакше використання символів "_ / \" краще відповідає духу питання.
Ніл

9

Python 2, 51 байт

M=lambda n:n<1or sum(M(k)*M(n-2-k)for k in range(n))

Використовує формулу Mathworld

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

Зберігає символи, додаючи M[n-1]термін у підсумок як k=n-1, що дає M[-1]*M[n-1], M[-1]=1як частину початкової умови.

Редагувати: На один знак коротше записувати суму рекурсивно:

M=lambda n,k=0:n<1or k<n and M(k)*M(n-2-k)+M(n,k+1)

Інші підходи, які виявилися довше:

M=lambda n,i=0:n and(i>0)*M(n-1,i-1)+M(n-1,i)+M(n-1,i+1)or i==0
M=lambda n:+(n<2)or(3*~-n*M(n-2)+(n-~n)*M(n-1))/(n+2)

8

Pyth, 15 байт

Ls*V+KyMb1+t_K1

Це визначає функцію y. Спробуйте в Інтернеті: Демонстрація

Пояснення:

Нехай y[n]буде n-те число Моцкіна. Я обчислюю y[n]за формулою

y[n] = dot product of (y[0], ..., y[n-1], 1) and (y[n-2], ..., y[0], 1)

Зауважте, що перший вектор більший за другий (крім випадків обчислення y[0]). У цьому випадку Pyth автоматично ігнорує 1 в кінці першого вектора, так що обидва вектора мають однакову довжину.

Ls*V+KyMb1+t_K1
L                 define a function y(b), which returns:
      yMb            compute the list [y[0], y[1], ..., y[b-1]]
     K               assign it to K
  *V                 vectorized multiplication of
    +K   1             * K with a 1 at the end
          +t_K1        * reverse(K), remove the first element, and append 1
 s                   return the sum (dot product)

Ця формула є варіантом однієї з формул, перелічених у OEIS. Це може бути трохи дурним. Через 1 в кінці першого вектора (які роблять довжини неоднаковими), я фактично не повинен давати рекурсії базовий випадок. І я сподівався, що ці двоє +...1можна якось пограти в гольф. Виявляється, я не можу.

Ви можете визначити подібну рекурсію з точковим добутком векторів однакової довжини та визначити базовий випадок y[0] = 1з тим самим числом байтів.


8

CJam (20 байт)

.5X]{__W%.*:++}qi*W=

Демонстрація в Інтернеті

Як Мего зазначила в коментарях до питання, це дуже тісно пов’язане з каталонськими номерами: змінити .5на 1та змістити індекс на один (або просто вилучити .5цілком і залишити індекс незмінним), щоб отримати каталонські номери.

Використовуваний рецидив є

a (n + 2) - a (n + 1) = a (0) * a (n) + a (1) * a (n-1) + ... + a (n) * a (0). [Бернхарт]

зі сторінки OEIS. Відповідний повтор для каталонських номерів вказаний як

a (n) = Sum_ {k = 0..n-1} a (k) a (n-1-k).


6

Серйозно, 21 байт

,;╗r`;τ╜█@;u@τ╣║\*`MΣ

Позичає якийсь код із рішення каталонських чисел Quintopia , зокрема покращення, яке я зробив у коментарях.

Я використовую таку формулу:

формула моцкіна

Оскільки nCkце 0 для k > n, я підсумовую до кінця n-1, оскільки всі ці значення будуть дорівнювати 0 і, таким чином, не впливають на суму.

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

Пояснення:

,;╗r`;τ╜█@;u@τ╣║\*`MΣ
,;╗                    push input, dupe, store one copy in register 0
   r                   push range(0, n) ([0,n-1])
    `             `M   map the function:
     ;τ╜█@               dupe k, push C(n, 2*k), swap with k
          ;u@τ╣║\        push the kth Catalan number
                 *       multiply
                    Σ  sum

C(n, 2*k)робить що зараз?
Аддісон Кримп

@FlagAsSpam C(n,k) = nCkабо кількість комбінацій kелементів із пулу nелементів.
Mego

О, це має сенс більше, ніж те, що я думав, що це було. +1.
Аддісон Кримп

@FlagAsSpam Я не думаю, що я хочу знати, що ти думав, що це ...
Mego

5

R, 64 байти

f=function(n)ifelse(n<2,1,f(n-1)+sum(rev(s<-sapply(2:n-2,f))*s))

Використовується також формула Mathworld відповіді пітона на @ xnor . Завдяки правилам пріоритету, 2:n-2це рівнозначно 0:(n-2).

Тестові приклади:

> f(0)
[1] 1
> f(1)
[1] 1
> f(5)
[1] 21
> f(10)
[1] 2188
> sapply(0:20,f)
 [1]        1        1        2        4        9       21       51      127
 [9]      323      835     2188     5798    15511    41835   113634   310572
[17]   853467  2356779  6536382 18199284 50852019

5

Математика, 31 30 байт

AppellF1[-#/2,.5,-#/2,2,4,4]&

Для задоволення, ось версія на 37 байт

Hypergeometric2F1[(1-#)/2,-#/2,2,4]&

та 52-байтну версію

SeriesCoefficient[1-x-Sqrt[1-2x-3x^2],{x,0,#+2}]/2&

4

Желе , 17 14 13 байт

×US;
1;HÇƓ¡1ị

Для цього використовується відношення рецидиву з відповіді @ PeterTaylor . Спробуйте в Інтернеті!

Як це працює

×US;      Define a helper link. Left argument: a (list)

×U        Multiply (×) a by its reverse (U).
  S       Compute the sum of the resulting list.
   ;      Prepend it to a.
          Return the result.

1;HÇƓ¡1ị  Define the main link.

1         Set the left argument to 1.
 ;H       Append the half of 1 to 1. Result: [1, 0.5].
    Ɠ     Read an integer n from STDIN.
   Ç ¡    Call the helper link (Ç) n times.
      1ị  Retrieve the result at index 1.

2

Математика, 44 42 34 байт

Sum[#!/(i!(i+1)!(#-2i)!),{i,0,#}]&

Версія на 35 байт:

Coefficient[(1+x+1/x)^#,x]/#&[#+1]&

2

Парі / ГП , 38 36 26 байт

n->(1+x+x^2)^n++/n\x^n++%x

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

Використовуючи рівняння (11) від MathWorld :

Mn=1n+1(n+11)2

(nk)2(nk)2xn+k(1+x+x2)n


14-байти Samau функції , використовуючи перше визначення коефіцієнта трехчлена: );;7 2D$ⁿ$)╡$÷. Я не буду публікувати це як відповідь, оскільки мова є новішою, ніж питання.
алефальфа

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

2

05AB1E , 13 12 байт

ÝI<ãʒ.øDŸQ}g

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

Хоча більшість відповідей використовують формулу або відношення повторення, це простий підхід підрахунку.

Кожен можливий шлях через сітку представлений списком його y координат. Для n сегментів є загальна кількість (n + 1) балів, але перший і останній обов'язково 0, так що залишають (n-1) точки для вказівки.

Ý           # range [0..n]
 I<         # n - 1
   ã        # cartesian power

Тепер у нас є список шляхів (ще не включаючи початковий і кінцевий 0). За конструкцією жоден з них ніколи не опускається нижче 0. Однак деякі з них мають незаконні схили (наприклад, стрибки з 0 до 2), тому нам потрібно їх відфільтрувати.

ʒ      }g   # count how many paths satistfy the following condition
 0.ø        # surround with 0
      Q     # is equal to
    DŸ      # its own fluctuating range

Ÿ- це вбудований діапазон коливань . Якщо є пара не сусідніх чисел, вона заповнить пропущені числа (наприклад, [0, 2] стає [0, 1, 2]). Лише юридичні шляхи залишаться незмінними.

Можливо, інтуїтивнішим способом перевірити наявність незаконних схилів було б üαà(стверджувати, що максимум парних абсолютних різниць дорівнює 1). Однак це не вистачає плоского шляху [0, 0, ... 0], який коштує один додатковий байт для виправлення.

Нарешті, зауважте, що фактичний код використовується там, де використовується це пояснення 0.ø. Замість оточення шляху 0, це оточує неявний вхід двома копіями шляху. Це перетворює систему координат догори дном і назовні, але інакше рівнозначно.





0

ES6, 44 байти

f=(n,k=0)=>n<1?1:k<n&&f(k)*f(n-2-k)+f(n,k+1)

Безпосередньо порт рекурсивного рішення @ xnor у програмі Python. Потреби n<1?1:тому, n<1||що принесуть f(0)повернення true.


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