Compute the Eulerian number
Jelly, 8 bytes
Œ!Z>2\Sċ
Try it online! (takes a while) or verify the smaller test cases.
How it works
Œ!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.
JavaScript (ES6), 50 46 45 bytes
f=(n,m,d=n-m)=>m?d&&f(--n,m)*++m+f(n,m-2)*d:1
Based on the recursive formula:
A(n, m) = (n - m)A(n - 1, m - 1) + (m + 1)A(n - 1, m)
Test cases
f=(n,m,d=n-m)=>m?d&&f(--n,m)*++m+f(n,m-2)*d:1
console.log(f( 0, 0)); // 1
console.log(f( 1, 0)); // 1
console.log(f( 1, 1)); // 0
console.log(f( 2, 0)); // 1
console.log(f( 2, 1)); // 1
console.log(f( 2, 2)); // 0
console.log(f( 3, 0)); // 1
console.log(f( 3, 1)); // 4
console.log(f( 3, 2)); // 1
console.log(f( 3, 3)); // 0
console.log(f( 4, 0)); // 1
console.log(f( 4, 1)); // 11
console.log(f( 4, 2)); // 11
console.log(f( 4, 3)); // 1
console.log(f( 4, 4)); // 0
console.log(f( 5, 1)); // 26
console.log(f( 7, 4)); // 1191
console.log(f( 9, 5)); // 88234
console.log(f(10, 5)); // 1310354
console.log(f(10, 7)); // 47840
console.log(f(10, 10)); // 0
console.log(f(12, 2)); // 478271
console.log(f(15, 6)); // 311387598411
console.log(f(17, 1)); // 131054
console.log(f(20, 16)); // 1026509354985
console.log(f(42, 42)); // 0
CJam (21 19 bytes - or 18 if argument order is free)
{\e!f{2ew::>1b=}1b}
This is an anonymous block (function) which takes n m
on the stack. (If it's permitted to take m n
on the stack then the \
can be saved). It computes all permutations and filters, so the online test suite must be rather limited.
Thanks to Martin for pointing out an approximation to filter-with-parameter
.
Dissection
{ 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
}
Note that the Eulerian numbers are symmetric: E(n, m) = E(n, n-m)
, so it's irrelevant whether you count falls or rises.
Efficiently: 32 bytes
{1a@{0\+_ee::*(;\W%ee::*W%.+}*=}
Online test suite.
This implements the recurrence on whole rows.
{ 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
}