Berechnen Sie die Eulersche Zahl


17

Die Eulersche Zahl A(n, m) ist die Anzahl der Permutationen, [1, 2, ..., n]bei denen genau mElemente größer als das vorherige Element sind. Diese werden auch als Aufstiege bezeichnet . Zum Beispiel, wenn n = 3es 3 gibt! = 6 Permutationen von[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 ...

So werden die Ausgänge A(3, m)für min [0, 1, 2, 3]sein

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

Dies ist auch die OEIS-Sequenz A173018 .

Regeln

  • Das ist also gewinnt der kürzeste Code.
  • Die Eingabe nist eine nicht negative Ganzzahl und meine Ganzzahl im Bereich [0, 1, ..., n].

Testfälle

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

Irgendwelche Grenzen n, m?
Loovjo

Es gibt keine Begrenzung, aber es ist nicht erforderlich, dass Ihre Einreichung einen Testfall in einer bestimmten Zeit vollständig ausführen kann. Sie müssen nur über die richtige Logik verfügen. Ich möchte, dass Übermittlungen Werte bis zu 20 verarbeiten, habe jedoch keine Leistungsanforderung gestellt, um Brute-Force-Lösungen zu ermöglichen, die möglicherweise nur bis zu 20 funktionieren n = 10.
Meilen

Kann der Eingang m> = n, n> 0 haben?
Feersum

Sollte nicht "m wird eine ganze Zahl im Bereich [0, 1, ..., n]" sein "... [0, 1, ..., n-1]"?
Jonathan Allan

@feersum Ihre Lösung kann auf mWunsch jede unterstützen , aber ich fordere nur, dass sie für 0 <= m <= n mit 0 <= n gültig ist .
Meilen

Antworten:


9

Gelee , 8 Bytes

Œ!Z>2\Sċ

Probieren Sie es online! (dauert eine Weile) oder überprüfen Sie die kleineren Testfälle .

Wie es funktioniert

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

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

Basierend auf der rekursiven Formel:

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

Testfälle


4

MATL , 10 Bytes

:Y@!d0>s=s

Probieren Sie es online!

Erläuterung

Betrachten wir als Beispiel Eingänge n=3,m=1 . Sie können ein %Symbol platzieren, um den Code von diesem Punkt an zu kommentieren und so die Zwischenergebnisse zu sehen. Beispielsweise zeigt der Link den Stapel nach dem ersten Schritt.

:      % 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 bis 19 Bytes - oder 18, wenn die Argumentreihenfolge frei ist)

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

Dies ist ein anonymer Block (Funktion), der n mden Stack übernimmt . (Wenn es erlaubt ist, m nden Stapel anzunehmen, \kann der gespeichert werden). Es berechnet alle Permutationen und Filter, also die Online-Testsuite eher eingeschränkt sein muss.

Vielen Dank an Martin für den Hinweis auf eine Annäherung an filter-with-parameter .

Präparation

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

Beachten Sie, dass die Eulersche Zahlen symmetrisch sind: E(n, m) = E(n, n-m) ist also unerheblich, ob Sie Stürze oder Anstiege zählen.

Effizient: 32 Bytes

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

Online-Testsuite .

Dies implementiert die Wiederholung für ganze Zeilen.

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

Es ist kürzer die Variable zu vermeiden , indem Sie eine Karte mit: {e!f{2ew::>1b=}1e=}. Oder nur zum Spaß:{e!f{2ew::>+:-}0e=}
Martin Ender

Das war natürlich dumm. Das 1e=in der ersten Lösung kann sein 1b.
Martin Ender

Sie können Ihre eigene Argumentationsreihenfolge verwenden
Meilen

3

Python, 55 56 Bytes

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

Alle Tests bei repl.it

Wendet die rekursive Formel auf OEIS an.
Beachten Sie, dass zu +(m+1)*a(n-1,m)Golf gespielt wird -~m*a(n-1,m).
(Kann boolesche Werte zurückgeben, um 1oder darzustellen 0. Gibt Truewann n<0 and m<=0oder zurück m<0.)


Es gibt verschiedene andere Möglichkeiten, die Kantenfälle zu behandeln. Es genügt m<1 ? 1 : m==n ? 0 : formula, äquivalent damit umzugehen m%n<1 ? (m<1) : formula; oder alternativ m<1 ? (n>=0) : formula.
Peter Taylor

Ich habe es bekommen, nur danke zu aktualisieren
Jonathan Allan

Da unsere Antworten sehr ähnlich sind und Ihre zuerst veröffentlicht wurde (und kürzer ist), werde ich meine löschen.
Loovjo

@ Loovjo Ein bisschen hektisches Tweaken obwohl :( Du hast trotzdem eine ^ Abstimmung von mir!
Jonathan Allan

3

Mathematica, 59 56 Bytes

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

Und hier ist eine 59-Byte-Version, die die Definition wörtlicher implementiert:

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

Warum nicht nur f[n_,m_]:=...für 49?
Jonathan Allan

@ JonathanAllan Ich bin nicht sicher, ob ich das verstehe. Wie geht das mit dem Base Case um?
Martin Ender

OK, etwas wurde zwischengespeichert - habe es gerade in einem neuen Arbeitsblatt getan und es ist mit Rekursionslimit fehlgeschlagen. :)
Jonathan Allan

Es gibt auch die Formel, die 46 Bytes verwendet Sum[Binomial[#+1,k](#2+1-k)^#(-1)^k,{k,0,#2}]&, um mehr Golf zu spielen
Meilen

3

Python, 53 Bytes

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

Rekursion von OEIS. Gibt einen Booleschen Wert aus, Trueals 1ob n==k.



2

GameMaker-Sprache, 62 Byte

Dies ist ein rekursives Skript, Adas auf der @ Arnauld-Formel basiert.

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

Habe das schon lange nicht mehr gesehen!
Tomsmeding

1

Perl, 98 Bytes

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

Basierend auf derselben Eigenschaft wie Arnauld's Antwort.


1

R, 72 Bytes

Rekursive Funktion nach der Logik von 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)

Diese Herausforderung erwies sich als ziemlich eng zwischen den verschiedenen Ansätzen, die ich ausprobiert habe. Wenn Sie zum Beispiel die Wikipedia-Formel verwenden und die Summe in einer Schleife durchlaufen, erhalten Sie 92 Bytes:

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

oder die vektorisierte Version für 87 Bytes:

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

und schließlich die Brute-Force-Lösung (103 Byte), die mithilfe des permutePakets und der Funktion eine Matrix aller Permutationen generiert allPerms. Dieser Ansatz funktioniert jedoch nur bis zu 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

Schläger 141 Bytes

(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

Testen:

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

Ausgabe:

1
4
1
0
11
26
1191

1

Eigentlich , 21 19 Bytes

Diese Antwort verwendet einen Algorithmus ähnlich dem, den Dennis in seiner Gelee-Antwort verwendet . Die ursprüngliche Definition zählt, <während ich zähle >. Dies endet am Ende als gleichwertig. Golfvorschläge sind willkommen.Probieren Sie es online!

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

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

Verwendet die Formel

Formel

Verwendung

   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

Erläuterung

+/@((!>:)~*(^~#\.)*_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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.