จำนวนที่ต้องการ


16

งาน

รับ 2 จำนวนเต็มบวกnและkที่ไหนn > kส่งออกจำนวน surjections จากชุดของnองค์ประกอบที่แตกต่างเพื่อชุดของkองค์ประกอบที่แตกต่าง

คำนิยาม

ฟังก์ชั่น f: S → T ถูกเรียกว่า surjection ถ้าทุกๆt∈Tมีs∈Sซึ่ง f (s) = t

ตัวอย่าง

เมื่อใดn=3และk=2ผลลัพธ์คือ6เนื่องจากมี6surjections จาก{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

Testcases

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

การอ้างอิง

เกณฑ์การให้คะแนน

นี่คือรหัสกอล์ฟคำตอบที่สั้นที่สุดในการชนะไบต์

ช่องโหว่มาตรฐานใช้


11
คำจำกัดความของความไม่แน่ใจจะเป็นสิ่งที่ดี
Stewie Griffin

3
เป็นความตั้งใจหรือไม่ที่nไม่เท่ากับk ?
เดนนิส

1
@ เดนนิสฉันชอบที่จะแยกกรณีขอบที่เป็นไปได้ทั้งหมดจากความท้าทายของฉัน
Leaky Nun

3
ที่ดูเหมือนว่าเป็นกรณีขอบสำคัญที่จะรวม ฉันเดาว่าคำตอบส่วนใหญ่ที่ทำงานกับ n> k จะทำงานให้กับ n == k ด้วยเช่นกัน แต่มันอาจช่วยให้การเล่นกอล์ฟลับๆล่อๆบางแห่ง
dylnan

@ ใครโหวตให้ปิดเหตุผลของคุณคืออะไร?
dylnan

คำตอบ:


5

เยลลี่ , 5 4 ไบต์

ṗṬML

นี่คือO (k n ) brute force solution

ลองออนไลน์!

มันทำงานอย่างไร

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

ลองออนไลน์!

คือนับ surjection ทำไม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 ไบต์โดยใช้ตัวดำเนินการมัด: ลองออนไลน์!
Laikoni

4

ลีน , 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 ns(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

คนแรกคือสิ่งที่เป็นจริงที่เกิดขึ้น: bijection ระหว่าง[0 ... s(m, n)-1]และ surjections จากบน[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(แบบลีนโดยอัตโนมัติจะระบุว่าประเภทของพวกเขาคือnatเพราะสิ่งต่อไปนี้)

  • fin (s m n)s m nเป็นประเภทของจำนวนธรรมชาติที่มีขนาดเล็กกว่า s m nที่จะทำให้ชาวเมืองหนึ่งมีจำนวนธรรมชาติและพิสูจน์ให้เห็นว่ามันมีขนาดเล็กกว่า

  • A ≃ B: bijection ระหว่างประเภทและชนิดA Bการบอกว่า bijection นั้นทำให้เข้าใจผิดเป็นจริงอย่างใดอย่างหนึ่งมีให้ฟังก์ชันผกผัน

  • { f : fin m → fin n // function.surjective f }ประเภทของ surjections จากไป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: ทำ recursion 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)

ลองออนไลน์!

ใช้หนึ่งในสูตรโดย Mario Catalani:

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

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

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.