Numero di sporgenze


16

Compito

Dati 2 numeri interi positivi ne k, dove n > k, hanno generato il numero di sporgenze da un insieme di nelementi distinguibili a un insieme di kelementi distinguibili.

Definizione

Una funzione f: S → T è chiamata suriezione se per ogni t∈T c'è s∈S tale che f (s) = t.

Esempio

Quando n=3e k=2, l'output è 6, poiché ci sono 6suriezioni da {1,2,3}a {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

Casi test

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

Riferimento

punteggio

Questo è . Vince la risposta più breve in byte.

Si applicano scappatoie standard .


11
Una definizione di surjection sarebbe piacevole.
Stewie Griffin,

3
È intenzionale che n non possa eguagliare k ?
Dennis,

1
@Dennis Mi piace escludere ogni possibile caso limite dalle mie sfide
Leaky Nun,

3
Sembra un importante caso limite da includere. La mia ipotesi è che la maggior parte delle risposte che funzionano per n> k funzionerà anche per n == k ma potrebbe consentire un po 'di golf subdolo da qualche parte
dylnan,

@ chi ha votato per chiudere qual è la tua ragione?
dylnan,

Risposte:


5

Gelatina , 5 4 byte

ṗṬML

Questa è una soluzione di forza bruta O (k n ) .

Provalo online!

Come funziona

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

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

Provalo online!

Perché il conteggio delle suriezioni s(m,n)=n*s(m-1,n-1)+n*s(m-1,n)?

per raccogliere nimmagini, posso farlo

  • spremere una [m]creazione singleton in uno dei nconfini che circondano i n-1gruppi
  • o aggiungi il mio nuovo min uno dei ngruppi già esistenti di[1..m-1]

Haskell , 38 byte

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

Provalo online!


2
38 byte utilizzando un operatore infix: provalo online!
Laikoni,

4

Lean , 66 byte

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

Provalo online!


Prova di correttezza

Provalo online!


Spiegazione

Cerchiamo di annullare la funzione:

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

La funzione è definita dal pattern matching e dalla ricorsione, entrambi con supporto integrato.

Definiamo s(m+1, n+1) = (n+1) * (s(m, n) + s(m, n+1)e s(0, 0) = 1, che lascia aperto s(m+1, 0)e s(0, n+1), entrambi definiti 0dall'ultimo caso.

Lean usa la sintassi del calcolo lamdba, così s m nè s(m, n).


Ora, la prova della correttezza: l'ho dichiarata in due modi:

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

Il primo è ciò che sta realmente accadendo: una biiezione tra [0 ... s(m, n)-1]e le sporgenze da [0 ... m-1]sopra [0 ... n-1].

Il secondo è come si dice di solito, cioè s(m, n)la cardinalità delle suriezioni da [0 ... m-1]su [0 ... n-1].


Lean usa la teoria dei tipi come base (invece della teoria dell'insieme). Nella teoria dei tipi, ogni oggetto ha un tipo che è inerente ad esso. natè il tipo di numeri naturali e la frase che 0è un numero naturale è espressa come 0 : nat. Diciamo che 0è di tipo nate che natha 0come abitante.

Le proposizioni (dichiarazioni / asserzioni) sono anche tipi: il loro abitante è una prova della proposizione.


  • def: Introdurremo una definizione (perché una biiezione è davvero una funzione, non solo una proposizione).

  • correctness: il nome della definizione

  • ∀ m n: per ogni me n(Lean deduce automaticamente che il loro tipo è nat, a causa di ciò che segue).

  • fin (s m n)è il tipo di numeri naturali che è inferiore a s m n. Per fare un abitante, si fornisce un numero naturale e una prova che è più piccolo di s m n.

  • A ≃ B: bijection tra il tipo Ae il tipo B. Dire che la biiezione è fuorviante, in quanto si deve effettivamente fornire la funzione inversa.

  • { f : fin m → fin n // function.surjective f }il tipo di sporgenze da fin ma fin n. Questa sintassi crea un sottotipo dal tipo fin m → fin n, ovvero il tipo di funzioni da fin ma fin n. La sintassi è { var : base type // proposition about var }.

  • λ m: ∀ var, proposition / type involving varè davvero una funzione che accetta varcome input, quindi λ mintroduce l'input. ∀ m n,è una scorciatoia per∀ m, ∀ n,

  • nat.rec_on m: fare ricorsione su m. Per definire qualcosa per m, definire la cosa per 0e quindi dare la cosa per k, costruire la cosa per k+1. Si noterebbe che questo è simile all'induzione, e in effetti questo è il risultato della corrispondenza Church-Howard . La sintassi è 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").

Heh, questo sta diventando lungo e sono solo sulla terza linea di correctness...


3

J , 19 byte

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

Provalo online!

Spiegazione

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

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

Provalo online!

Implementa una delle formule di Mario Catalani:

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

o alternativamente:

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

che produce lo stesso numero di byte in R.


2

Python 2 , 56 53 50 byte

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

Provalo online!

-3 byte grazie a H.PWiz.

-3 byte grazie a Dennis.

  • Se n<knon tutto kpuò essere mappato, quindi non ci sono suriezioni. n/k andse ne occupa.
  • Prendere f(0,0)=1ci dà l'unico caso di base diverso da zero di cui abbiamo bisogno. 1/k orraggiunge questo.


2

Brain-Flak , 142 byte

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

Provalo online!

Questo utilizza la formula standard di inclusione-esclusione.

Non riesco a scrivere una spiegazione completa in questo momento, ma ecco una spiegazione di alto livello:

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

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

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


2

Buccia , 7 byte

#`¦ḣ¹π²

Provalo online!

Spiegazione

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


1

05AB1E , 10 byte

sLsãʒêgQ}g

Provalo online!

Spiegazione

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.