Обчисліть ейлерові числа


17

Ейлерову число A(n, m) є число перестановок , [1, 2, ..., n]в яких рівно mелементах більше , ніж попередній елемент. Вони також називаються підйомами . Наприклад, якщо n = 3, є 3! = 6 перестановок[1, 2, 3]

1 2 3
 < <  2 elements are greater than the previous

1 3 2
 < >  1 ...

2 1 3
 > <  1 ...

2 3 1
 < >  1 ...

3 1 2
 > <  1 ...

3 2 1
 > >  0 ...

Тож результати для A(3, m)for min [0, 1, 2, 3]будуть

A(3, 0) = 1
A(3, 1) = 4
A(3, 2) = 1
A(3, 3) = 0

Також це послідовність OEIS A173018 .

Правила

  • Це тому найкоротший код виграє.
  • Вхід nбуде невід’ємним цілим числом і mбуде цілим числом у діапазоні [0, 1, ..., n].

Випробування

n   m   A(n, m)
0   0   1
1   0   1
1   1   0
2   0   1
2   1   1
2   2   0
3   0   1
3   1   4
3   2   1
3   3   0
4   0   1
4   1   11
4   2   11
4   3   1
4   4   0
5   1   26
7   4   1191
9   5   88234
10  5   1310354
10  7   47840
10  10  0
12  2   478271
15  6   311387598411
17  1   131054
20  16  1026509354985
42  42  0

Будь-які обмеження на n, m?
Loovjo

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

Чи може вхід мати m> = n, n> 0?
feersum

Чи не повинно бути, "m буде цілим числом у діапазоні [0, 1, ..., n]" бути "... [0, 1, ..., n-1]"?
Джонатан Аллан

@feersum Ваше рішення може підтримувати будь-яке, mза бажанням, але я вимагаю, щоб воно було дійсним для 0 <= m <= n з 0 <= n .
милі

Відповіді:


9

Желе , 8 байт

Œ!Z>2\Sċ

Спробуйте в Інтернеті! (займає деякий час) або перевірити менші тестові випадки .

Як це працює

Œ!Z>2\Sċ  Main link. Arguments: n, m

Œ!        Generate the matrix of all permutations of [1, ..., n].
  Z       Zip/transpose, placing the permutations in the columns.
   >2\    Compare columns pairwise with vectorizing greater-than.
          This generates a 1 in the column for each rise in that permutation.
      S   Compute the vectorizing sum of the columns, counting the number of rises.
       ċ  Count how many times m appears in the computed counts.

6

JavaScript (ES6), 50 46 45 байт

f=(n,m,d=n-m)=>m?d&&f(--n,m)*++m+f(n,m-2)*d:1

На основі рекурсивної формули:

A(n, m) = (n - m)A(n - 1, m - 1) + (m + 1)A(n - 1, m)    

Тестові справи


4

MATL , 10 байт

:Y@!d0>s=s

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

Пояснення

Розглянемо в якості прикладу входів n=3,m=1 . Ви можете розмістити %символ, щоб прокоментувати код з цього моменту і таким чином побачити проміжні результати. Наприклад, посилання показує стек після першого кроку.

:      % Input n implicitly. Push [1 2 ... n]
       % STACK: [1 2 ... n]
Y@     % Matrix of all permutations, one on each row
       % STACK: [1 2 3; 1 3 2; 2 1 3; 2 3 1; 3 1 2; 3 2 1]
!      % Transpose
       % STACK: [1 1 2 2 3 3; 2 3 1 3 1 2; 3 2 3 1 2 1]
d      % Consecutive differences along each column
       % STACK: [1 2 -1 1 -2 -1; 1 -1 2 -2 1 -1]
0>     % True for positive entries
       % STACK: [1 1 0 1 0 0; 1 0 1 0 1 0]
s      % Sum of each column
       % STACK: [2 1 1 1 1 0]
=      % Input m implicitly. Test each entry for equality with m
       % STACK: [0 1 1 1 1 0]
s      % Sum. Implicitly display
       % STACK: 4

4

CJam ( 21 19 байт - або 18, якщо порядок аргументів вільний)

{\e!f{2ew::>1b=}1b}

Це анонімний блок (функція), який приймає n mстек. (Якщо дозволено приймати m nстек, тоді \можна зберегти). Він обчислює всі перестановки та фільтри, тому онлайн-тестовий набір повинен бути досить обмеженим.

Дякую Мартіну за те, що він вказав наближення до filter-with-parameter.

Розсічення

{        e# Define a block. Stack: n m
  \      e#   Flip the stack to give m n
  e!f{   e#   Generate permutations of [0 .. n-1] and map with parameter m
    2ew  e#     Stack: m perm; generate the list of n-1 pairs of consecutive
         e#     elements of perm
    ::>  e#     Map each pair to 1 if it's a rise and 0 if it's a fall
    1b   e#     Count the falls
    =    e#     Map to 1 if there are m falls and 0 otherwise
  }
  1b     e#   Count the permutations with m falls
}

Зауважте, що ейлерові числа симетричні: E(n, m) = E(n, n-m)тому не має значення, чи підраховуєте ви падіння чи підйом.

Ефективно: 32 байти

{1a@{0\+_ee::*(;\W%ee::*W%.+}*=}

Інтернет-тестовий набір .

Це реалізує повторення на цілі ряди.

{          e# Define a block. Stack: n m
  1a@      e#   Push the row for n=0: [1]; and rotate n to top of stack
  {        e#   Repeat n times:
           e#     Stack: m previous-row
    0\+_   e#     Prepend a 0 to the row and duplicate
    ee::*  e#     Multiply each element by its index
           e#     This gives A[j] = j * E(i-1, j-1)
    (;     e#     Pop the first element, so that A[j] = (j+1) * E(i-1, j)
    \W%    e#     Get the other copy of the previous row and reverse it
    ee::*  e#     Multiply each element by its index
           e#     This gives B[j] = j * E(i-1, i-1-j)
    W%     e#     Reverse again, giving B[j] = (i-j) * E(i-1, j-1)
    .+     e#     Pointwise addition
  }*
  =        e#   Extract the element at index j
}

Це коротше , щоб уникнути змінної за допомогою карти: {e!f{2ew::>1b=}1e=}. Або просто для розваги:{e!f{2ew::>+:-}0e=}
Мартін Ендер

Це було дурно, звичайно. 1e=У першому розчині може бути 1b.
Мартін Ендер

Вам дозволяється використовувати власне замовлення аргументів
миль

3

Пітон, 55 56 байт

a=lambda n,m:n>=m>0and(n-m)*a(n-1,m-1)-~m*a(n-1,m)or m<1

Всі тести на repl.it

Застосовує рекурсивну формулу на OEIS.
Зауважте, що +(m+1)*a(n-1,m)в гольф -~m*a(n-1,m).
(Може повернути булеві значення для представлення 1або 0. Повертається, Trueколи n<0 and m<=0або m<0.)


Існують різні інші способи вирішення крайових корпусів. Досить впоратися m<1 ? 1 : m==n ? 0 : formula, рівнозначно m%n<1 ? (m<1) : formula; або альтернативно m<1 ? (n>=0) : formula.
Пітер Тейлор

Я отримав це, лише оновивши подяку
Джонатан Аллан

Оскільки наші відповіді дуже схожі, і ваша була опублікована першою (і коротше), я продовжую і видаляю свою.
Loovjo

@Loovjo Трохи шаленого настроювання, хоча :( Ви все одно отримаєте ^ голосування від мене!
Джонатан Алан

3

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

_~f~0=1
n_~f~m_:=If[m>n,0,(n-m)f[n-1,m-1]+(m+1)f[n-1,m]]

А ось 59-байтна версія, що реалізує визначення більш буквально:

Count[Count@1/@Sign/@Differences/@Permutations@Range@#,#2]&

Чому б не лише f[n_,m_]:=...49?
Джонатан Аллан

@JonathanAllan Я не впевнений, що розумію. Як це поводиться з базовим випадком?
Мартін Ендер

Гаразд, щось було кешоване - просто це було зроблено в новому аркуші, і це не вдалося з обмеженням рекурсії. :)
Джонатан Аллан

Існує також формула, яка використовує 46 байт, Sum[Binomial[#+1,k](#2+1-k)^#(-1)^k,{k,0,#2}]&які можуть бути можливими для гольфу більше
миль

3

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

t=lambda n,k:n and(n-k)*t(n-1,k-1)-~k*t(n-1,k)or k==0

Рекурсія від ОЕІС. Виводить булеві, Trueяк 1коли n==k.



2

Мова GameMaker, 62 байти

Це рекурсивний сценарій, Aзаснований на формулі @ Арнольда.

n=argument0;m=argument1;return (n-m)*A(n-1,m-1)+(m+1)*A(n-1,m)

Цього часу не бачив!
tomsmeding

1

Perl, 98 байт

sub a{my($b,$c)=@_;return$c?$c>$b?0:($b-$c)*a($b-1,$c-1)+($c+1)*a($b-1,$c):1;}print a(@ARGV[0,1]);

Виходячи з тієї ж властивості, що й відповідь Арнальда.


1

R, 72 байти

Рекурсивна функція, що відповідає логіці на OEIS.

A=function(n,m)if(!m)1 else if(m-n)0 else(n-m)*A(n-1,m-1)+(m+1)*A(n-1,m)

Цей виклик виявився досить близьким між різними підходами, які я намагався. Наприклад, використовуючи формулу wikipedia і перебираючи певну суму, виникла 92 байти:

function(n,m){s=0;if(!n)1 else for(k in -1:m+1)s=c(s,(-1)^k*choose(n+1,k)*(m+1-k)^n);sum(s)}

або векторизовану версію на 87 байт:

function(n,m)if(!m)1 else sum(sapply(-1:m+1,function(k)(-1)^k*choose(n+1,k)*(m+1-k)^n))

і нарешті жорстоке рішення (103 байти), яке генерує матрицю всіх перестановок за допомогою permuteпакета та функції allPerms. Цей підхід працює лише до цих n<8пір.

function(n,m){if(!m)1 else sum(apply(rbind(1:n,permute:::allPerms(n)),1,function(x)sum(diff(x)>0))==m)}

1

Ракетка 141 байт

(count(λ(x)(= x m))(for/list((t(permutations(range 1(+ 1 n)))))(count
(λ(x)x)(for/list((i(sub1 n)))(>(list-ref t(+ 1 i))(list-ref t i))))))

Безумовно:

(define (f n m)
  (let* ((l (range 1 (add1 n)))                ; create a list till n
         (pl (permutations l))                 ; get all permutations
         (enl (for/list ((t pl))               ; check each permutation; 
                (define rl
                  (for/list ((i (sub1 n)))     ; check if an element is a 'rise'
                    (> (list-ref t (add1 i))
                       (list-ref t i))))
                (count (lambda(x)x) rl))))     ; how many numbers are 'rises'
    (count (lambda(x) (= x m)) enl)))          ; how many permutations had m rises
                                               ; i.e. Eulerian number

Тестування:

(f 3 0)
(f 3 1)
(f 3 2)
(f 3 3)
(f 4 2)
(f 5 1)
(f 7 4)

Вихід:

1
4
1
0
11
26
1191

1

Насправді , 21 19 байт

У цій відповіді використовується алгоритм, аналогічний тому, який використовує Денніс у своїй відповіді на Jelly . Початкове визначення враховується, <поки я рахую >. Це в кінцевому підсумку є рівнозначним. Пропозиції з гольфу вітаються. Спробуйте в Інтернеті!

;R╨`;\ZdX"i>"£MΣ`Mc

Ungolfing

         Implicit input m, then n.
;        Duplicate n. Stack: n, n, m
R        Push range [1..n].
╨        Push all n-length permutations of the range.
`...`M   Map the following function over each permutation p.
  ;\       Duplicate and rotate p so that we have a list of the next elements of p.
  Z        Zip rot_p and p.
           (order of operands here means the next element is first,
            so we need to use > later)
  dX       Remove the last pair as we don't compare the last and first elements of the list.
  "i>"£    Create a function that will flatten a list and check for a rise.
  M        Map that function over all the pairs.
  Σ        Count how many rises there are in each permutation.
c        Using the result of the map and the remaining m, 
          count how many permutations have m rises.
         Implicit return.


0

J, 28 байт

+/@((!>:)~*(^~#\.)*_1^])i.,]

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

formula

Використання

   f =: +/@((!>:)~*(^~#\.)*_1^])i.,]
   0 f 0
1
   1 f 0
1
   1 f 1
0
   (f"+i.,]) 6
1 57 302 302 57 1 0
   20x f 16x
1026509354985

Пояснення

+/@((!>:)~*(^~#\.)*_1^])i.,]  Input: n (LHS), m (RHS)
                        i.    Range [0, 1, ..., m-1]
                           ]  Get m
                          ,   Join to get k = [0, 1, ..., m]
                      ]       Get k
                   _1^        Raise -1 to each in k
              #\.               Get the length of each suffix of k
                                Forms the range [m+1, m, ..., 2, 1]
            ^~                  Raise each value by n
                  *           Multiply elementwise with (-1)^k
    (   )~                      Commute operators
      >:                        Increment n
     !                          Binomial coefficient, C(n+1, k)
          *                   Multiply elementwise
+/@                           Reduce by addition to get the sum and return
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.