Numero de extracciones

16

Tarea

Dados 2 enteros positivos ny k, donde n > k, emiten el número de extracciones de un conjunto de nelementos distinguibles a un conjunto de kelementos distinguibles.

Definición

Una función f: S → T se llama surjection si por cada t∈T hay s∈S tal que f (s) = t.

Ejemplo

Cuando n=3y k=2, la salida es 6, ya que hay 6extracciones de {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

Casos de prueba

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

Referencia

Puntuación

Este es el . La respuesta más corta en bytes gana.

Se aplican lagunas estándar .

Monja permeable
fuente
11
Una definición de surjection estaría bien.
Stewie Griffin
3
¿Es intencional que n no sea igual a k ?
Dennis
1
@Dennis Me gusta excluir todos los casos límite posibles de mis desafíos
Leaky Nun
3
Ese parece ser un caso importante importante para incluir. Mi conjetura es que la mayoría de las respuestas que funcionan para n> k también funcionarán para n == k, pero podría permitir un poco de golf furtivo en algún lugar
dylnan
@ ¿Quién votó para cerrar cuál es su razón?
dylnan

Respuestas:

5

Jalea , 5 4 bytes

ṗṬML

Esta es una solución de fuerza bruta O (k n ) .

Pruébalo en línea!

Cómo funciona

ṗṬ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
fuente
4

Haskell , 48 bytes

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

Pruébalo en línea!

¿Por qué es el recuento de surjection s(m,n)=n*s(m-1,n-1)+n*s(m-1,n) ?

para cosechar nimágenes, puedo

  • exprimir una [m]creación singleton en cualquiera de los nlímites que rodeann-1 grupos
  • o agregar mi nuevo men cualquiera de nlos grupos ya existentes de[1..m-1]

Haskell , 38 bytes

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

Pruébalo en línea!

Roman Czyborra
fuente
2
38 bytes utilizando un operador infijo: ¡ Pruébelo en línea!
Laikoni
4

Lean , 66 bytes

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

Pruébalo en línea!


Prueba de corrección

Pruébalo en línea!


Explicación

Dejemos de ungolf la función:

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

La función se define por la coincidencia de patrones y la recursividad, que tienen soporte incorporado.

Definimos s(m+1, n+1) = (n+1) * (s(m, n) + s(m, n+1)y s(0, 0) = 1, que deja abierto s(m+1, 0)y s(0, n+1), los cuales se definen como 0el último caso.

Lean utiliza la sintaxis de cálculo lamdba, por lo que s m nes así s(m, n).


Ahora, la prueba de corrección: lo dije de dos maneras:

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

El primero es lo que realmente está sucediendo: una biyección entre [0 ... s(m, n)-1]y las sobrejeturas de [0 ... m-1]sobre [0 ... n-1].

El segundo es cómo se suele decir, que s(m, n)es la cardinalidad de las sobreyecciones de [0 ... m-1]sobre [0 ... n-1].


Lean utiliza la teoría de tipos como base (en lugar de la teoría de conjuntos). En la teoría de tipos, cada objeto tiene un tipo inherente. nates el tipo de números naturales, y la declaración que 0es un número natural se expresa como 0 : nat. Decimos que 0es de tipo nat, y quenat tiene0 como habitante.

Las proposiciones (declaraciones / aserciones) también son tipos: su habitante es una prueba de la proposición.


  • def: Vamos a introducir una definición (porque una biyección es realmente una función, no solo una proposición).

  • correctness: el nombre de la definición

  • ∀ m n: por cada my n(Lean infiere automáticamente que su tipo es nat, debido a lo que sigue).

  • fin (s m n)es el tipo de números naturales que es menor que s m n. Para hacer un habitante, uno proporciona un número natural y una prueba de que es más pequeño que s m n.

  • A ≃ B: biyección entre el tipo Ay el tipo B. Decir bijection es engañoso, ya que uno realmente tiene que proporcionar la función inversa.

  • { f : fin m → fin n // function.surjective f }El tipo de sobrejeciones de fin ma fin n. Esta sintaxis crea un subtipo a partir del tipo fin m → fin n, es decir, el tipo de funciones desde fin mhasta fin n. La sintaxis es la siguiente { var : base type // proposition about var }.

  • λ m: ∀ var, proposition / type involving vares realmente una función que toma varcomo entrada, por lo que λ mintroduce la entrada. ∀ m n,es abreviatura de∀ m, ∀ n,

  • nat.rec_on m: hacer recursividad en m. Para definir algo para m, definir la cosa para 0y luego dar la cosa para k, construir la cosa para k+1. Uno notaría que esto es similar a la inducción, y de hecho esto es el resultado de la correspondencia entre la Iglesia y Howard . La sintaxis es la siguiente 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").

Je, esto se está haciendo largo y solo estoy en la tercera línea de correctness...

Monja permeable
fuente
3

J , 19 bytes

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

Pruébalo en línea!

Explicación

-/@(^~*]!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)
millas
fuente
-/@(^~*]!0{])]-i.
FrownyFrog
2

R , 49 bytes

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

Pruébalo en línea!

Implementa una de las fórmulas de 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

que produce el mismo número de bytes en R.

Giuseppe
fuente
2

Python 2 , 56 53 50 bytes

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

Pruébalo en línea!

-3 bytes gracias a H.PWiz.

-3 bytes gracias a Dennis.

  • Si n<kno todos kpueden ser mapeados, entonces no hay sobrejeturas.n/k andse encarga de esto.
  • Tomar f(0,0)=1nos da el único caso base distinto de cero que necesitamos. 1/k orlogra esto.
dylnan
fuente
2

Brain-Flak , 142 bytes

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

Pruébalo en línea!

Esto usa la fórmula estándar de inclusión-exclusión.

No puedo escribir una explicación completa en este momento, pero aquí hay una explicación de alto nivel:

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

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

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

Pari / GP , 38 bytes

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

Pruébalo en línea!

Usando la fórmula de Vladimir Kruchinin en OEIS:

E.g.f.: (exp(x)-1)^k = sum T(n,k)x^n/n!
alephalpha
fuente
2

Casco , 7 bytes

#`¦ḣ¹π²

Pruébalo en línea!

Explicación

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

05AB1E , 10 bytes

sLsãʒêgQ}g

Pruébalo en línea!

Explicación

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
fuente