Liczba podejrzeń

16

Zadanie

Biorąc pod uwagę 2 dodatnie liczby całkowite, ni kgdzie n > kwypisuje liczbę wypukłości z zestawu nwyróżnialnych elementów do zestawu kwyróżnialnych elementów.

Definicja

Funkcja f: S → T nazywa się odrzuceniem, jeżeli dla każdego t∈T istnieje s∈S takie, że f (s) = t.

Przykład

Kiedy n=3i k=2, dane wyjściowe są 6, ponieważ istnieją 6przypuszczenia od {1,2,3}do {1,2}:

  1. 1↦1, 2↦1, 3↦2
  2. 1↦1, 2↦2, 3↦1
  3. 1↦1, 2↦2, 3↦2
  4. 1↦2, 2↦1, 3↦1
  5. 1↦2, 2↦1, 3↦2
  6. 1↦2, 2↦2, 3↦1

Przypadki testowe

n k output
5 3 150
8 4 40824
9 8 1451520

Odniesienie

Punktacja

To jest . Najkrótsza odpowiedź w bajtach wygrywa.

Obowiązują standardowe luki .

Leaky Nun
źródło
11
Przydałaby się definicja przypuszczenia.
Stewie Griffin,
3
Czy jest celowe, że n nie może być równe k ?
Dennis,
1
@Dennis Lubię wykluczyć wszystkie możliwe przypadki krawędzi z moich wyzwań
Leaky Nun
3
Wydaje się, że to ważny przypadek do uwzględnienia. Domyślam się, że większość odpowiedzi, które działają dla n> k, będzie również działać dla n == k, ale może to pozwolić na jakieś podstępne
granie w
@ ktokolwiek głosował za zamknięciem jaki jest twój powód?
dylnan,

Odpowiedzi:

5

Galaretka , 5 4 bajtów

ṗṬML

Jest to O (K n ) roztworu brute force.

Wypróbuj online!

Jak to działa

ṗṬML  Main link. Left argument: k. Right argument: n.

ṗ     Cartesian power; yield the list of all n-tuples over {1, ..., k}.
      Each tuple represents a (not necessarily surjective) function from
      {1, ..., n} to {1, ..., k}.
 Ṭ    Apply the "untruth" atom to each tuple.
      Ṭ maps a list of indices to an array with 1's at those indices, and exactly
      as many zeroes as needed to build the array.
      Examples:
           [1, 2, 3, 3, 3] -> [1, 1, 1]
           [1, 3, 5]       -> [1, 0, 1, 0, 1]
           [2, 6, 2, 4, 4] -> [0, 1, 0, 1, 0, 1]
  M   Yield all indices of maximal elements, i.e., all indices of [1] * k.
   L  Take the length.
Dennis
źródło
4

Haskell , 48 bajtów

s(_,1)=1
s(1,_)=0
s(m,n)=n*(s(m-1,n-1)+s(m-1,n))

Wypróbuj online!

Dlaczego liczy się obrzucenie s(m,n)=n*s(m-1,n-1)+n*s(m-1,n)?

w celu zebrania nzdjęć mogę to zrobić

  • ściśnij [m]stworzenie singletona w dowolną z ngranic otaczających n-1grupy
  • lub dodaj mój nowy mdo dowolnej z njuż istniejących grup[1..m-1]

Haskell , 38 bajtów

m#n|n<2=1|m<2=0|o<-m-1=n*(o#(n-1)+o#n)

Wypróbuj online!

Roman Czyborra
źródło
2
38 bajtów przy użyciu operatora infix: Wypróbuj online!
Laikoni
4

Lean , 66 bajtów

def s:_->nat->nat|(m+1)(n+1):=(n+1)*(s m n+s m(n+1))|0 0:=1|_ _:=0

Wypróbuj online!


Dowód poprawności

Wypróbuj online!


Wyjaśnienie

Odholfujmy funkcję:

def s : nat->nat->nat
| (m+1) (n+1) := (n+1)*(s m n + s m (n+1))
| 0     0     := 1
| _     _     := 0

Funkcja jest zdefiniowana przez dopasowanie wzorca i rekurencję, które mają wbudowane wsparcie.

Definiujemy s(m+1, n+1) = (n+1) * (s(m, n) + s(m, n+1)i s(0, 0) = 1, które pozostawiają otwarte, s(m+1, 0)i s(0, n+1)oba są zdefiniowane jako 0ostatni przypadek.

Lean zastosowania składnia lamdba rachunek, tak s m njest s(m, n).


Teraz dowód poprawności: stwierdziłem to na dwa sposoby:

def correctness : ∀ m n, fin (s m n) ≃ { f : fin m → fin n // function.surjective f } :=
λ m, nat.rec_on m (λ n, nat.cases_on n s_zero_zero (λ n, s_zero_succ n)) $
λ m ih n, nat.cases_on n (s_succ_zero m) $ λ n,
calc fin (s (nat.succ m) (nat.succ n))
   ≃ (fin (n + 1) × (fin (s m n + s m (n + 1)))) :
  (fin_prod _ _).symm
... ≃ (fin (n + 1) × (fin (s m n) ⊕ fin (s m (n + 1)))) :
  equiv.prod_congr (equiv.refl _) (fin_sum _ _).symm
... ≃ (fin (n + 1) × ({f : fin m → fin n // function.surjective f} ⊕
         {f : fin m → fin (n + 1) // function.surjective f})) :
  equiv.prod_congr (equiv.refl _) (equiv.sum_congr (ih n) (ih (n + 1)))
... ≃ {f // function.surjective f} : s_aux m n

def correctness_2 (m n : nat) : s m n = fintype.card { f : fin m → fin n // function.surjective f } :=
by rw fintype.of_equiv_card (correctness m n); simp

Pierwszym z nich jest to, co się naprawdę dzieje: bijection pomiędzy [0 ... s(m, n)-1]i przypuszczeniami z [0 ... m-1]na [0 ... n-1].

Drugim jest to, jak zwykle się mówi, to s(m, n)jest liczebność przypuszczeń z [0 ... m-1]na [0 ... n-1].


Lean używa teorii typów jako podstawy (zamiast teorii mnogości). W teorii typów każdy obiekt ma swój nieodłączny typ. natjest rodzajem liczb naturalnych, a wyrażenie, które 0jest liczbą naturalną, wyraża się jako 0 : nat. Mówimy, że 0jest to typowe nati natma to 0jako mieszkaniec.

Twierdzenia (stwierdzenia / twierdzenia) są również typami: ich mieszkaniec jest dowodem zdania.


  • def: Wprowadzimy definicję (ponieważ bijection jest tak naprawdę funkcją, a nie tylko propozycją).

  • correctness: nazwa definicji

  • ∀ m n: dla każdego mi n(Lean automatycznie wywnioskuje, że ich typ jest nat, z powodu tego, co następuje).

  • fin (s m n)to rodzaj liczb naturalnych, który jest mniejszy niż s m n. Aby stworzyć mieszkańca, podaje się liczbę naturalną i dowód, że jest ona mniejsza niż s m n.

  • A ≃ B: bijection między typem Aa typem B. Mówienie bijection jest mylące, ponieważ w rzeczywistości trzeba zapewnić funkcję odwrotną.

  • { f : fin m → fin n // function.surjective f }rodzaj przypuszczeń od fin mdo fin n. Ta składnia buduje podtyp na podstawie typu fin m → fin n, tj. Typu funkcji od fin mdo fin n. Składnia jest następująca { var : base type // proposition about var }.

  • λ m: ∀ var, proposition / type involving varto tak naprawdę funkcja, która przyjmuje vardane wejściowe, więc λ mwprowadza dane wejściowe. ∀ m n,jest na krótką rękę∀ m, ∀ n,

  • nat.rec_on m: wykonaj rekursję w dniu m. Aby zdefiniować coś dla m, zdefiniuj rzecz dla, 0a następnie daj rzecz dla k, zbuduj rzecz dla k+1. Można zauważyć, że jest to podobne do indukcji i rzeczywiście jest to wynikiem korespondencji Church-Howard . Składnia jest następująca nat.rec_on var (thing when var is 0) (for all k, given "thing when k is k", build thing when var is "k+1").

Hej, robi się to długo i jestem tylko na trzeciej linii correctness...

Leaky Nun
źródło
3

J , 19 bajtów

-/@(^~*]!0{])],i.@-

Wypróbuj online!

Wyjaśnienie

-/@(^~*]!0{])],i.@-  Input: n (LHS), k (RHS)
                  -  Negate k
               i.@   Range [k-1, k-2, ..., 0]
             ]       Get RHS
              ,      Join, forms [k, k-1, ..., 0]
   (        )        Dyad between n (LHS), [k, k-1, ..., 0] (RHS)
           ]           Get RHS
         0{            Select value at index 0
       ]               Get RHS
        !              Binomial coefficient
    ^~                 Raise each in RHS to power of n
      *                Multiply
-/@                  Reduce from right to left using subtraction (forms alternating sum)
mile
źródło
-/@(^~*]!0{])]-i.
FrownyFrog
2

R , 49 bajtów

function(n,k,j=0:k)((-1)^(k-j)*j^n)%*%choose(k,j)

Wypróbuj online!

Implementuje jedną z formuł autorstwa Mario Catalani:

T(n, k) = Sum_{j=0..k} (-1)^(k-j)*j^n*binomial(k, j)

lub na przemian:

T(n, k) = Sum_{j=0..k} (-1)^j*binomial(k, j)*(k-j)^n

co daje taką samą liczbę bajtów w R.

Giuseppe
źródło
2

Python 2 , 56 53 50 bajtów

f=lambda n,k:n/k and(1/k or f(n-1,k-1)+f(n-1,k))*k

Wypróbuj online!

-3 bajty dzięki H.PWiz.

-3 bajty dzięki Dennisowi.

  • Jeśli n<knie wszystko kmożna zmapować, nie ma żadnych przypuszczeń.n/k andzajmuje się tym.
  • Biorąc f(0,0)=1daje nam jedyną niezerową skrzynkę podstawową, której potrzebujemy. 1/k orosiąga to.
dylnan
źródło
2

Brain-Flak , 142 bajty

({}<({}()){({}[(())]<<>{({}({})<>)<>}{}>)}{}>)<>{<>(({}<>)<{({}[()]<([])({([{}]()({}))([{}]({}))}{}[{}])>)}{}({}<>)>)<>}<>{}{}{({}<>[{}])<>}<>

Wypróbuj online!

Wykorzystuje to standardową formułę włączenia / wyłączenia.

W tej chwili nie mogę napisać pełnego wyjaśnienia, ale oto wyjaśnienie wysokiego poziomu:

# Compute k-th row of Pascal's triangle
({}<({}()){({}[(())]<<>{({}({})<>)<>}{}>)}{}>)<>

# Multiply each element by n^j (and reverse to other stack)
{<>(({}<>)<{({}[()]<([])({([{}]()({}))([{}]({}))}{}[{}])>)}{}({}<>)>)<>}

# Compute alternating sum
<>{}{}{({}<>[{}])<>}<>
Nitrodon
źródło
2

Pari / GP , 38 bajtów

(n,k)->Pol(exp(x+O(x^n))-1)^k*n!\x^n%x

Wypróbuj online!

Korzystając z formuły Vladimira Kruchinina z OEIS:

E.g.f.: (exp(x)-1)^k = sum T(n,k)x^n/n!
alephalpha
źródło
2

Łuska , 7 bajtów

#`¦ḣ¹π²

Wypróbuj online!

Wyjaśnienie

#`¦ḣ¹π²  Inputs: n (²), implicit k (¹)
     π²  Cartesian power of [1..k] to n
#        Count if:
   ḣ¹      Range [1..k]
 `¦        Is a subset
Fyr
źródło
1

05AB1E , 10 bajtów

sLsãʒêgQ}g

Wypróbuj online!

Wyjaśnienie

sLsã       # Cartesian product of range(k) repeated n times
    ʒ   }  # Filter by ...
     êgQ   # Connected uniquified length == k  (every item in range(k) appears at least once)
         g # Count
Kaldo
źródło