Tính số Euler


17

Số Euler A(n, m) là số lượng hoán vị [1, 2, ..., n]trong đó mcác phần tử chính xác lớn hơn phần tử trước. Đây cũng được gọi là tăng . Ví dụ, nếu n = 3, có 3! = 6 hoán vị của[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 ...

Vì vậy, đầu ra A(3, m)cho mtrong [0, 1, 2, 3]sẽ là

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

Ngoài ra, đây là trình tự OEIS A173018 .

Quy tắc

  • Đây là nên mã ngắn nhất sẽ thắng.
  • Đầu vào nsẽ là một số nguyên không âm và msẽ là một số nguyên trong phạm vi [0, 1, ..., n].

Các trường hợp thử nghiệm

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

Bất kỳ giới hạn trên n, m?
Loovjo

Không có giới hạn, nhưng không yêu cầu trình của bạn có thể thực hiện hoàn toàn một trường hợp thử nghiệm trong một khoảng thời gian nhất định, chỉ có logic chính xác. Tốt hơn là, tôi muốn đệ trình để xử lý các giá trị lên tới 20, nhưng tôi đã bỏ nó mà không có yêu cầu về hiệu suất để cho phép các giải pháp vũ phu chỉ có thể hoạt động tối đa n = 10.
dặm

Đầu vào có thể có m> = n, n> 0 không?
frageum

Không nên, "m sẽ là một số nguyên trong phạm vi [0, 1, ..., n]" là "... [0, 1, ..., n-1]"?
Jonathan Allan

@feersum Giải pháp của bạn có thể hỗ trợ bất kỳ mnếu muốn, nhưng tôi chỉ yêu cầu rằng nó hợp lệ cho 0 <= m <= n với 0 <= n .
dặm

Câu trả lời:


9

Thạch , 8 byte

Œ!Z>2\Sċ

Hãy thử trực tuyến! (mất một lúc) hoặc xác minh các trường hợp thử nghiệm nhỏ hơn .

Làm thế nào nó hoạt động

Œ!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 byte

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

Dựa trên công thức đệ quy:

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

Các trường hợp thử nghiệm


4

MATL , 10 byte

:Y@!d0>s=s

Hãy thử trực tuyến!

Giải trình

Xem xét như một ví dụ đầu vào n=3,m=1 . Bạn có thể đặt một %biểu tượng để nhận xét mã từ thời điểm đó trở đi và do đó xem kết quả trung gian. Ví dụ: liên kết hiển thị ngăn xếp sau bước đầu tiên.

:      % 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 byte - hoặc 18 nếu thứ tự đối số là miễn phí)

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

Đây là một khối ẩn danh (chức năng) n m trong ngăn xếp. (Nếu nó được phép mang m nvào ngăn xếp thì \có thể được lưu). Nó tính toán tất cả các hoán vị và bộ lọc, vì vậy bộ kiểm tra trực tuyến phải khá hạn chế.

Cảm ơn Martin đã chỉ ra một xấp xỉ filter-with-parameter.

Mổ xẻ

{        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
}

Lưu ý rằng các số Euler là đối xứng: E(n, m) = E(n, n-m)vì vậy, nó không liên quan cho dù bạn đếm giảm hay tăng.

Hiệu quả: 32 byte

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

Bộ kiểm tra trực tuyến .

Điều này thực hiện sự tái phát trên toàn bộ hàng.

{          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
}

Nó ngắn hơn để tránh biến bằng cách sử dụng bản đồ : {e!f{2ew::>1b=}1e=}. Hoặc chỉ để giải trí:{e!f{2ew::>+:-}0e=}
Martin Ender

Điều đó thật ngu ngốc, tất nhiên. Các 1e=giải pháp đầu tiên có thể được 1b.
Martin Ender

Bạn được phép sử dụng thứ tự đối số của riêng bạn
dặm

3

Python, 55 56 byte

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

Tất cả các bài kiểm tra tại repl.it

Áp dụng công thức đệ quy trên OEIS.
Lưu ý rằng +(m+1)*a(n-1,m)được chơi golf -~m*a(n-1,m).
(Có thể trả về giá trị boolean để đại diện 1hoặc 0. Trả vềTrue khi n<0 and m<=0hoặc m<0.)


Có nhiều cách khác nhau để xử lý các trường hợp cạnh. Nó đủ để xử lý m<1 ? 1 : m==n ? 0 : formula, tương đương m%n<1 ? (m<1) : formula; hoặc cách khác m<1 ? (n>=0) : formula.
Peter Taylor

Tôi đã nhận được nó, chỉ cần cập nhật cảm ơn
Jonathan Allan

Vì câu trả lời của chúng tôi rất giống nhau và câu trả lời của bạn đã được đăng đầu tiên (và ngắn hơn), tôi sẽ tiếp tục và xóa câu trả lời của mình.
Loovjo

@Loovjo Một chút tinh chỉnh điên cuồng mặc dù :( Dù sao bạn cũng nhận được ^ phiếu bầu từ tôi!
Jonathan Allan

3

Toán học, 59 56 byte

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

Và đây là phiên bản 59 byte thực hiện định nghĩa theo nghĩa đen hơn:

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

Tại sao không chỉ f[n_,m_]:=...cho 49?
Jonathan Allan

@Jonathan ALLan Tôi không chắc là tôi hiểu. Làm thế nào mà xử lý các trường hợp cơ sở?
Martin Ender

OK, một cái gì đó đã được lưu trữ - chỉ cần thực hiện trong một bảng tính mới và nó đã thất bại với giới hạn đệ quy. :)
Jonathan Allan

Ngoài ra còn có các công thức trong đó sử dụng 46 byte Sum[Binomial[#+1,k](#2+1-k)^#(-1)^k,{k,0,#2}]&mà có thể có thể để golf hơn
dặm

3

Python, 53 byte

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

Đệ quy từ OEIS. Đầu ra Boolean Truenhư 1khi nào n==k.


2

MATLAB / Octave, 40 byte

@(n,m)sum(sum(diff((perms(1:n))')>0)==m)

Đây là một cổng của câu trả lời MATL của tôi, dưới dạng một hàm ẩn danh. Gọi nó làans(7,4) .

Hãy thử nó tại Ideone .


2

Ngôn ngữ GameMaker, 62 byte

Đây là tập lệnh đệ quy Adựa trên công thức của @ Arnauld.

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

Lâu rồi tôi không thấy RATNG!
tomsmeding

1

Perl, 98 byte

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]);

Dựa trên cùng một tài sản như câu trả lời của Arnauld.


1

R, 72 byte

Hàm đệ quy theo logic trên 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)

Thử thách này hóa ra khá gần giữa các cách tiếp cận khác nhau mà tôi đã thử. Chẳng hạn, sử dụng công thức wikipedia và lặp qua tổng số dẫn đến 92 byte:

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)}

hoặc phiên bản vector hóa cho 87 byte:

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

và cuối cùng là giải pháp lực lượng vũ phu (103 byte) tạo ra ma trận của tất cả các hoán vị bằng cách sử dụng permutegói và hàm allPerms. Cách tiếp cận này chỉ hoạt động đến n<8mặc dù.

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

1

Vợt 141 byte

(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))))))

Ung dung:

(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

Kiểm tra:

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

Đầu ra:

1
4
1
0
11
26
1191

1

Thật ra , 21 19 byte

Câu trả lời này sử dụng thuật toán tương tự như thuật toán mà Dennis sử dụng trong câu trả lời Jelly của mình . Định nghĩa ban đầu tính <trong khi tôi đếm >. Điều này kết thúc tương đương cuối cùng. Gợi ý chơi golf chào mừng. Hãy thử trực tuyến!

;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 byte

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

Sử dụng công thức

formula

Sử dụng

   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

Giải trình

+/@((!>:)~*(^~#\.)*_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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.