サジェクションの数


16

仕事

2つの正の整数nとが与えられた場合k、はn > kn区別可能な要素のセットから区別可能な要素のセットへの射影の数を出力しkます。

定義

関数f:S→Tは、すべてのt∈Tに対してf(s)= tであるようなs∈Sがある場合、サジェクションと呼ばれます。

ときn=3k=2、出力は6あるので、6からsurjections {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
nkに等しくなることは意図的ではありませんか?
デニス

1
@デニス私は挑戦からすべての可能性のあるエッジケースを除外したい
リーキー修道女

3
これは、含めるべき重要なエッジケースのようです。私の推測では、nの仕事> kの意志も仕事nの== kはそれはいくつかの卑劣なゴルフのどこかのためにできる可能性があることを、ほとんどの答えである
dylnan

@あなたの理由は何ですか?
ディルナン

回答:


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]

Haskell、38バイト

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

オンラインでお試しください!


2
中置演算子を使用して38バイト:オンラインで試してみてください!
ライコニ

4

リーン、66バイト

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

オンラインでお試しください!


正当性の証明

オンラインでお試しください!


説明

関数をungolfしましょう:

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)and を定義しますs(0, 0) = 1。これは、開いたままにs(m+1, 0)しますs(0, n+1)。どちらも0、最後のケースまでに定義されています。

リーンはlamdba微積分構文を使用するため、s m nですs(m, n)


さて、正しさの証拠:私は2つの方法でそれを述べました:

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]とのsurjections [0 ... m-1][0 ... n-1]

もう一つは、通常、その、記載されている方法ですs(m, n)からsurjectionsのカーディナリティです[0 ... m-1][0 ... n-1]


リーンは、(集合論の代わりに)型理論を基礎として使用します。型理論では、すべてのオブジェクトに固有の型があります。natは自然数のタイプであり、自然数であるステートメント0はと表され0 : natます。私たちはそれ0がタイプnatであり、それnatが持っていると言います0住民としてているます。

命題(ステートメント/アサーション)もタイプです:それらの住民は命題の証拠です。


  • def:定義を導入します(全単射は、単なる命題ではなく実際に機能であるため)。

  • correctness:定義の名前

  • ∀ m n:for 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 }surjectionsのタイプfin mfin n。この構文は、タイプfin m → fin n、つまりからの関数のタイプからサブタイプを構築fin mfin 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")です。

ねえ、これは長くなっていて、私は3行目です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)

オンラインでお試しください!

マリオ・カタラニの公式の1つを実装します。

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

Rで同じバイトカウントが生成されます。


2

パイソン256の53 50バイト

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

オンラインでお試しください!

H.PWizのおかげで-3バイト。

デニスのおかげで-3バイト。

  • n<kすべてkをマッピングできない場合は、このように推測はありません。n/k andこれを処理します。
  • 取得f(0,0)=1することで、必要なゼロ以外のベースケースのみが得られます。1/k orこれを達成します。


2

Brain-Flak、142バイト

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

オンラインでお試しください!

これは、標準的な包含/除外式を使用します。

現時点では完全な説明を書くことはできませんが、概要を以下に示します。

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

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

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




弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.