Кількість сюжетів


16

Завдання

Дано 2 додатних цілих числа nі k, де n > k, виведіть кількість відхилень від набору nвідмінних елементів до набору kвідмінних елементів.

Визначення

Функція f: S → T називається сюржекцією, якщо для кожного t∈T є s∈S такий, що f (s) = t.

Приклад

Коли n=3і k=2, вихід є 6, оскільки існують 6перевищення від {1,2,3}до {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

Тестові шафи

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

Довідково

Оцінка балів

Це . Найкоротша відповідь у байтах виграє.

Застосовуються стандартні лазівки .


11
Визначення викидання було б добре.
Стюі Гріффін

3
Чи навмисно, що n не може дорівнювати k ?
Денніс

1
@Dennis Мені подобається виключати будь-який можливий випадок із моїх викликів
Leaky Nun

3
Це здається важливим кращим випадком, який слід включити. Я гадаю, що більшість відповідей, які працюють на n> k, також працюватимуть за n == k, але це може
спричинити

@ хто б не проголосував, щоб закрити, яка ваша причина?
Ділнан

Відповіді:


5

Желе , 5 4 байти

ṗṬML

Це рішення O (k n ) грубої сили.

Спробуйте в Інтернеті!

Як це працює

ṗṬ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.

4

Haskell , 48 байт

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

Спробуйте в Інтернеті!

Чому рахується сюжет s(m,n)=n*s(m-1,n-1)+n*s(m-1,n)?

аби збирати nзображення, я можу і будь-який

  • витіснити однотонне [m]творіння в будь-яку з nмеж навколишніх n-1груп
  • або додати мою нову mв будь-яку з nуже існуючих груп[1..m-1]

Хаскелл , 38 байт

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

Спробуйте в Інтернеті!


2
38 байт за допомогою оператора інфіксації: Спробуйте в Інтернеті!
Лайконі

4

Lean , 66 байт

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

Спробуйте в Інтернеті!


Доказ правильності

Спробуйте в Інтернеті!


Пояснення

Дозвольмо виконувати функцію:

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

Функція визначається узгодженням шаблону та рекурсією, обидва з яких мають вбудовану підтримку.

Ми визначаємо s(m+1, n+1) = (n+1) * (s(m, n) + s(m, n+1)і s(0, 0) = 1, що залишає відкритим, s(m+1, 0)і s(0, n+1)обидва визначені 0як останній випадок.

Lean використовує синтаксис обчислення lamdba, так і s m nє s(m, n).


Тепер доказ коректності: я заявив це двома способами:

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

Перший - це те, що відбувається насправді: біекція між [0 ... s(m, n)-1]та вилучення з [0 ... m-1]на [0 ... n-1].

Другий - як це констатується, тобто s(m, n)кардинальність сюжетів з [0 ... m-1]на [0 ... n-1].


Lean використовує теорію типів як свою основу (замість теорії множин). У теорії типів кожен об'єкт має властивий йому тип. nat- це тип натуральних чисел, а твердження, що 0є натуральним числом, виражається як 0 : nat. Ми говоримо, що 0це тип nat, і це natє 0як житель.

Пропозиції (твердження / твердження) також є типами: їх житель є доказом пропозиції.


  • def: Ми збираємося ввести визначення (адже біекція - це дійсно функція, а не лише пропозиція).

  • correctness: назва визначення

  • ∀ m n: для кожного mі n(Lean автоматично робить висновок про те, що їх тип nat, через те, що випливає далі).

  • fin (s m n)- тип натуральних чисел, менший за s m n. Щоб зробити мешканця, треба надати натуральну кількість і доказ того, що він менший, ніж s m n.

  • A ≃ B: біекція між типом Aі типом B. Скажімо, біекція вводить в оману, оскільки людина насправді повинна забезпечувати зворотну функцію.

  • { f : fin m → fin n // function.surjective f }тип сюжетів від fin mдо fin n. Цей синтаксис будує підтип від типу fin m → fin n, тобто тип функцій від fin mдо fin n. Синтаксис є { var : base type // proposition about var }.

  • λ m: ∀ var, proposition / type involving varдійсно є функцією, яка приймає varяк вхід, тому λ mвводить вхід. ∀ m n,є короткою рукою для∀ m, ∀ n,

  • nat.rec_on m: зробити рекурсію на m. Щоб визначити щось для m, визначте річ для, 0а потім дайте річ для k, побудуйте річ для k+1. Можна було б помітити, що це схоже на індукцію, і справді це є результатом листування Церкви-Говарда . Синтаксис є 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").

Хе, це стає довго, і я лише на третьому рядку correctness...


3

J , 19 байт

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

Спробуйте в Інтернеті!

Пояснення

-/@(^~*]!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)

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

2

R , 49 байт

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

Спробуйте в Інтернеті!

Реалізує одну з формул Маріо Каталані:

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

або по черзі:

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

що дає однаковий підрахунок байтів у Р.


2

Python 2 , 56 53 50 байт

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

Спробуйте в Інтернеті!

-3 байти завдяки H.PWiz.

-3 байти завдяки Деннісу.

  • Якщо n<kне все kможна нанести на карту, то немає ніяких сюжетів. n/k andдбає про це.
  • Прийняття f(0,0)=1дає нам єдиний нульовий базовий випадок, який нам потрібен. 1/k orцього досягає.


2

Мозок-Флак , 142 байти

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

Спробуйте в Інтернеті!

Для цього використовується стандартна формула включення-виключення.

Наразі не можу написати повне пояснення, але ось пояснення на високому рівні:

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

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

# Compute alternating sum
<>{}{}{({}<>[{}])<>}<>




Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.