Euler sayısını hesapla


17

Euler sayısı A(n, m) permütasyon sayısı [1, 2, ..., n]tam olarak hangi melemanlarının daha önceki elemandan daha büyüktür. Bunlara yükseliş de denir . Örneğin, n = 33 varsa! = 6 permütasyon[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 ...

İçin çıkışlar Yani A(3, m)için mde [0, 1, 2, 3]olacak

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

Ayrıca, bu OEIS dizisi A173018'dir .

kurallar

  • Bu yani kısa kod kazanır.
  • Girdi nnegatif olmayan bir tamsayı molacak ve aralıkta bir tamsayı olacaktır [0, 1, ..., n].

Test Durumları

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

Üzerinde herhangi bir sınır var n, mmı?
Loovjo

Sınır yoktur, ancak gönderiminizin belirli bir süre içinde bir test vakasını tamamen yürütebilmesi gerekli değildir, sadece doğru mantığa sahip olmanız gerekir. Tercihen, gönderimlerin 20'ye kadar değerleri işlemesini istiyorum, ancak sadece çalışabilecek kaba kuvvet çözümlerine izin vermek için bir performans gereksinimi olmadan bıraktım n = 10.
mil

Girişte m> = n, n> 0 olabilir mi?
feersum

"M [0, 1, ..., n] aralığında bir tam sayı olacak mı?" "" [0, 1, ..., n-1] "olmamalı mı?
Jonathan Allan

@feersum Çözümün herhangi destekleyebilir mistenirse, ama ben sadece 0 <= geçerli olmasını gerektirir m <= n 0 <= n .
mil

Yanıtlar:


9

Jöle , 8 bayt

Œ!Z>2\Sċ

Çevrimiçi deneyin! (biraz zaman alır) veya daha küçük test durumlarını doğrulayın .

Nasıl çalışır

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

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

Özyinelemeli formüle dayanarak:

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

Test senaryoları


4

MATL , 10 bayt

:Y@!d0>s=s

Çevrimiçi deneyin!

açıklama

Örnek girdi olarak göz önünde n=3,m=1 . Bu %noktadan itibaren kodu yorumlamak ve böylece ara sonuçları görmek için bir sembol yerleştirebilirsiniz . Örneğin, bağlantı ilk adımdan sonra yığını gösterir.

:      % 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 bayt - veya argüman sırası ücretsizse 18)

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

Bu, n myığını alan anonim bir bloktur (işlev) . ( m nYığını almasına izin verilirse \kaydedilebilir). Tüm permütasyonları ve filtreleri hesaplar, böylece çevrimiçi test paketi oldukça sınırlı olmalıdır.

Martin'e bir yaklaşımı işaret ettiği için teşekkürler filter-with-parameter.

teşrih

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

Euler sayılarının simetrik olduğuna dikkat edin: Düşüş E(n, m) = E(n, n-m)ya da yükseliş saymanız önemli değildir.

Verimli: 32 bayt

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

Çevrimiçi test paketi .

Bu, tüm satırlarda yinelemeyi uygular.

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

Bir haritayı kullanarak değişken önlemek için daha kısa: {e!f{2ew::>1b=}1e=}. Ya da sadece eğlence için:{e!f{2ew::>+:-}0e=}
Martin Ender

Tabii ki aptalcaydı. 1e=Birinci çözelti içinde olabilir 1b.
Martin Ender

Kendi argüman siparişinizi kullanmanıza izin verilir
mil

3

Python, 55 56 bayt

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

Repl.it sitesindeki tüm testler

Özyinelemeli formülü OEIS üzerine uygular.
+(m+1)*a(n-1,m)Golfçü unutmayın -~m*a(n-1,m).
(Boole değerlerini temsil etmek için 1veya öğesini döndürebilir 0. Veya Truene zaman döndürür .)n<0 and m<=0m<0


Kenar kasalarını işlemenin başka yolları da vardır. Bu işlemek için yeterli m<1 ? 1 : m==n ? 0 : formulaeşdeğer olarak m%n<1 ? (m<1) : formula; veya alternatif olarak m<1 ? (n>=0) : formula.
Peter Taylor

Anladım, sadece güncelleniyorum
Jonathan Allan

Cevaplarımız birbirine çok benzediğinden ve sizinkiler önce yayınlandığından (ve daha kısa olduğundan), devam edip benimkini sileceğim.
Loovjo

@Loovjo Yine de biraz çılgınca ince ayar :( Yine de benden bir ^ oy aldınız!
Jonathan Allan

3

Mathematica, 59 56 bayt

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

Ve tanımı daha anlamıyla uygulayan 59 baytlık bir sürüm:

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

Neden sadece f[n_,m_]:=...49 için değil ?
Jonathan Allan

@JonathanAllan Anladığımdan emin değilim. Bu temel durumu nasıl ele alıyor?
Martin Ender

Tamam, bir şey önbelleğe alındı ​​- yeni bir çalışma sayfasında yaptım ve özyineleme sınırıyla başarısız oldu. :)
Jonathan Allan

Sum[Binomial[#+1,k](#2+1-k)^#(-1)^k,{k,0,#2}]&Daha fazla golf
mil

3

Python, 53 bayt

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

OEIS'ten özyineleme. Ne zaman Trueolduğu gibi Boole yazıyor .1n==k


2

MATLAB / Oktav, 40 bayt

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

Bu, MATL cevabımın anonim bir fonksiyon şeklinde bir limanıdır. Olarak adlandırın ans(7,4).

Ideone'da deneyin .


2

GameMaker Dili, 62 bayt

Bu A@ Arnauld'un formülüne dayanan özyinelemeli bir komut dosyasıdır .

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

Bunu bir süredir görmedim!
36'da tomsmeding

1

Perl, 98 bayt

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

Arnauld'un cevabı ile aynı mülke dayanarak.


1

R, 72 bayt

OEIS mantığını izleyen özyinelemeli fonksiyon.

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)

Bu zorluğun, denediğim farklı yaklaşımlar arasında oldukça yakın olduğu ortaya çıktı. Örneğin, wikipedia formülünü kullanmak ve toplamın üzerinde döngü yapmak 92 bayt ile sonuçlandı:

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

veya 87 bayt için vectorized versiyonu:

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

ve son olarak permutepaketi ve işlevi kullanarak tüm permütasyonların bir matrisini üreten kaba kuvvet çözeltisi (103 bayt) allPerms. Bu yaklaşım sadece işe yarıyor 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

Raket 141 bayt

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

Ungolfed:

(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

Test yapmak:

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

Çıktı:

1
4
1
0
11
26
1191

1

Aslında , 21 19 bayt

Bu cevap, Dennis'in Jelly cevabında kullandığı algoritmaya benzer bir algoritma kullanıyor . Orijinal tanım <ben sayarken önemlidir >. Bu, sonunda eşdeğer olur. Golf önerileri hoş geldiniz. Çevrimiçi deneyin!

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

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

Formülü kullanır

formula

kullanım

   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

açıklama

+/@((!>:)~*(^~#\.)*_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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.