N'inci Bell Numarasını Çıkarın


13

Bir Bell numarası ( OEIS A000110 ), bir n etiketli (farklı) öğeyi bölmenin yol sayısıdır. 0. Bell numarası 1 olarak tanımlanır.

Bazı örneklere bakalım (bölümler için alt kümeleri ve parantezleri belirtmek için parantez kullanıyorum):

1: {1}
2: {[1,2]}, {[1],[2]}
3: {[1,2,3]}, {[1,2],[3]}, {[1,3],[2]}, {[2,3],[1]}, {[1],[2],[3]}

Bell sayılarını hesaplamanın birçok yolu vardır ve bunlardan herhangi birini kullanmakta özgürsünüz. Burada bir yol tarif edilecektir:

Bell sayılarını hesaplamanın en kolay yolu, binom katsayıları için Pascal üçgenine benzeyen bir sayı üçgeni kullanmaktır. Bell numaraları üçgenin kenarlarında görünür. 1'den başlayarak, üçgendeki her yeni satır, bir önceki satırdaki son girdiyi ilk girdi olarak alarak ve ardından her yeni girdiyi sol komşu artı sol üst komşusuna ayarlayarak oluşturulur:

1
1    2
2    3    5
5    7   10   15
15  20   27   37   52

0 dizinleme veya 1 dizinleme kullanabilirsiniz. 0 dizinleme kullanırsanız, bir girdi 3çıktılanmalıdır 5, ancak 21 dizinleme kullanıyorsanız çıktı alınmalıdır .

Programınız çıktı olarak 15. Bell numarasına kadar çalışmalıdır 1382958545. Teorik olarak, programınız daha büyük sayıları işleyebilmelidir (başka bir deyişle, çözümleri kodlamayın). DÜZENLEME: Üçgen yöntemiyle hesaplanmadığı için 0 (0 dizinleme için) veya 1 (1 dizinleme için) girdisini işlemeniz gerekmez.

Test senaryoları (0-endeksleme varsayarak):

0 ->  1 (OPTIONAL)
1 ->  1 
2 ->  2 
3 ->  5 
4 ->  15 
5 ->  52 
6 ->  203 
7 ->  877 
8 ->  4140 
9 ->  21147 
10 -> 115975 
11 -> 678570 
12 -> 4213597 
13 -> 27644437 
14 -> 190899322 
15 -> 1382958545

Doğrudan Bell sayıları üreten yerleşik bir yöntem (Wolfram Dili'nde BellB [n] gibi) kullanan yanıtlar rekabetçi değildir.

En kısa kod (bayt cinsinden) kazanır.


Eğer 0-indeksleme kullanırsanız, bir girdi 3gereken çıkış5 Bu çıktıya olur 15, doğru? Ve 1 endeksleme ile çıktı5
Luis Mendo

Bunun ardındaki mantık 0-zil sayısını 0-indekslemede indeks 0 ve 1-indekslemede indeks 1 olarak saymaktı. Yolunuz daha açık olabilir, ancak mevcut cevaplar böyle çalışıyor, bu yüzden şimdi değiştiremiyorum. Bu siteye birkaç saat önce katıldım
rigged

Ancak 1 indeksleme ile girdinin 3çıktısı alması gerektiğini söylüyorsunuz 2. O zaman girdi 11-endeksleme ile ne verirdi ?
Luis Mendo

1 -> 1, 2 -> 1, 3 -> 2 (0, 1 ve 2. Bell numaralarına karşılık gelir), 0 -> 1, 1 -> 1, 2 -> 2 yerine Yanlış kullanıyorum terminoloji
hileli

Sanırım anladım. İlk 1 örnek tablonuzda ve çıktıda eksik, bu da beni
şaşırttı

Yanıtlar:


2

Jöle , 9 bayt

ṖµṀcæ.߀‘

Bu formülü kullanır

formül

bu da n <2 olduğunda kapalıdır .

Çevrimiçi deneyin!

Nasıl çalışır

ṖµṀcæ.߀‘  Main link. Argument: n

Ṗ          Pop; yield A := [1, ..., n-1].
 µ         Begin a new, monadic chain with argument A.
  Ṁ        Maximum; yield n-1.
   c       Combinatons; compute (n-1)C(k) for each k in A.
      ߀   Recursively map the main link over A.
    æ.     Take the dot product of the results to both sides.
        ‘  Increment; add 1 to the result.

8

JavaScript (ES6), 47 bayt

f=(n,a=[b=1])=>n--?f(n,[b,...a.map(e=>b+=e)]):b
f=(n,a=[b=1])=>--n?f(n,[b,...a.map(e=>b+=e)]):b

Birincisi 0 dizinli, ikincisi 1 dizinli.


8

Haskell, 36 bayt

head.(iterate(last>>=scanl(+))[1]!!)

Üçgen yöntemini kullanır, 0, 0 tabanlı doğru işler.



4

Mathematica, 24 bayt

Sum[k^#/k!,{k,0,∞}]/E&

@Kelly Lowder'dan -13 bayt!


Sum[k^#/k!,{k,0,∞}]/E&sadece 24 bayttır
Kelly Lowder

3

Jöle , 14 12 11 bayt

ṫ0;⁸+\
1Ç¡Ḣ

Çevrimiçi deneyin!

Tam ile Jelly güçlü noktalarını isabet yoktu dinamik girişi ¡, her bir dizi ve prepending atomu olmaması (bir baytlık modifiye ;@veya ters- ).


3

CJam (19 bayt)

Xa{X\{X+:X}%+}qi*0=

Çevrimiçi demo

teşrih

Xa         e# Start with an array [1]
{          e# Repeat...
  X\       e#   Put a copy of X under the current row
  {X+:X}%  e#   Map over x in row: push (X+=x)
  +        e#   Prepend that copy of last element of the previous row to get the next row
}
qi*        e# ... input() times
0=         e# Select the first element

3

MATL , 14 bayt

:dtEw1Zh1Ze/Yo

Girdi 0 tabanlıdır. Çevrimiçi deneyin!

açıklama

Bu formülü kullanır

resim açıklamasını buraya girin

burada p F q ( a 1 , ..., a p ; b 1 , ..., b q ; x ) genelleştirilmiş hipergeometrik işlevdir .

:      % Implictly input n. Push array [1 2 ... n]
d      % Consecutive differences: array [1 ... 1] (n-1 entries)
tE     % Duplicate, multiply by 2: array [2 ... 2] (n-1 entries)
w      % Swap
1      % Push 1
Zh     % Hypergeometric function
1Ze    % Push number e
/      % Divide
Yo     % Round (to prevent numerical precision issues). Implicitly display

3

Python , 42 bayt

f=lambda n,k=0:n<1or k*f(n-1,k)+f(n-1,k+1)

Çevrimiçi deneyin!

Özyinelemeli formül, nöğeleri bölümlere yerleştirmekten gelir . Sırayla her öğe için, yerleştirip yerleştirmeyeceğimize karar veririz:

  • Mevcut bir bölüme, kseçimleri olan
  • kGelecekteki öğeler için seçenek sayısını artıran yeni bir bölüm başlatmak için

Her iki şekilde de yerleştirilecek kalan nöğe sayısını azaltır . Demek ki tekrarlı formül var f(n,k)=k*f(n-1,k)+f(n-1,k+1)ve f(0,k)=1birlikte, f(n,0)n'inci Bell numarası.


2

Python 2 , 91 bayt

s=lambda n,k:n*k and k*s(n-1,k)+s(n-1,k-1)or n==k
B=lambda n:sum(s(n,k)for k in range(n+1))

Çevrimiçi deneyin!

B (n) ikinci türdeki Stirling sayılarının toplamı olarak hesaplanmıştır.


Güzel bir çözüm. İkinci tür Stirling numaraları için yerleşik bir kullanımın Bell numaralarını hesaplamasına izin verileceğini unutmayın (Mathematica veya benzeri)
hile

İki baytı doğrudan şu tanımına kaydedebilirsiniz s: özyinelemeli çağrılar her zaman azalır nve ilk dönemde kkaybedebileceğiniz bir bölüm yoktur *k.
Peter Taylor

Veya tüm sıralar üzerinde çalışarak bir lambda düzleştirerek bir demet kaydedebilirsiniz:B=lambda n,r=[1,0]:n and B(n-1,[k*r[k]+r[k-1]for k in range(len(r))]+[0])or sum(r)
Peter Taylor

Fonksiyonun olarak Bözyinelemeli değildir ve son cevabın, sen atlayabilirsiniz B=için 2 bayt kaydetmek
Felipe Nardi Batista

2

MATLAB, 128103 bayt

function q(z)
r(1,1)=1;for x=2:z
r(x,1)=r(x-1,x-1);for y=2:x
r(x,y)=r(x,y-1)+r(x-1,y-1);end
end
r(z,z)

Kendini açıklayıcı. Bir satırın sonunda noktalı virgül atlanması sonucu yazdırır.

Luis Mendo sayesinde 25 bayt kurtardı.




2

Ohm , 15 bayt

2°M^┼ⁿ^!/Σ;αê/≈

Çevrimiçi deneyin!

Dobinski'nin forumla'sını kullanır (B (0) yay için bile çalışır ).

açıklama

2°M^┼ⁿ^!/Σ;αê/≈
2°        ;     # Push 100
  M             # Do 100 times...
   ^             # Push index of current iteration
    ┼ⁿ           # Take that to the power of the user input
      ^!         # Push index factorial
        /        # Divide
         Σ       # Sum stack together
           αê   # Push e (2.718...)
             /  # Divide
              ≈ # Round to nearest integer (Srsly why doesn't 05AB1E have this???)

2

Python (79 bayt)

B=lambda n,r=[1]:n and B(n-1,[r[-1]+sum(r[:i])for i in range(len(r)+1)])or r[0]

Python 2'de çevrimiçi demo , ancak Python 3'te de çalışıyor.

Bu, Aitken'in üçgenini golfik bir döngü için özyinelemeli bir lambda kullanarak oluşturur.



1

J, 17 bayt

0{]_1&({+/\@,])1:

Üçgen hesaplama yöntemini kullanır.

Çevrimiçi deneyin!

açıklama

0{]_1&({+/\@,])1:  Input: integer n
               1:  The constant 1
  ]                Identity function, get n
   _1&(       )    Call this verb with a fixed left argument of -1 n times
                   on itself starting with a right argument [1]
             ]       Get right argument
       {             Select at index -1 (the last item)
            ,        Join
        +/\@         Find the cumulative sums
0{                 Select at index 0 (the first item)


1

Python 3 , 68 60 bayt

Üçgenin basit özyinelemeli yapısı, ancak pratik amaçlar için çılgınca verimsiz. 15. Bell numarasının hesaplanması TIO'nun zaman aşımına uğramasına neden olur, ancak makinemde çalışır.

Bu, 1 dizinleme kullanır ve True1 yerine döndürür .

f=lambda r,c=0:r<1or c<1and f(r-1,r-1)or f(r-1,c-1)+f(r,c-1)

Çevrimiçi deneyin!


8 bayt kazandığı için @FelipeNardiBatista'ya teşekkürler!


60 bayt . (0,1) yerine boolean döndüren pitonda kabul edilebilir
Felipe Nardi Batista


1

Alice , 22 bayt

/oi
\1@/t&wq]&w.q,+k2:

Çevrimiçi deneyin!

Üçgen yöntemini kullanır. N = 0 için, bunun yerine B (1) hesaplanır, bu da uygun bir şekilde B (0) 'a eşittir.

açıklama

Sıralı modda girdi alan, kardinal modda işleyen ve sonucu sıralı modda çıkaran programlar için standart bir şablondur. 1Bu değeri girişin altındaki yığına koymak için şablona A eklenmiştir.

Program üçgenin her bir satırını hesaplamak için yığını genişleyen bir dairesel kuyruk olarak kullanır. Birinciyi geçen her yineleme sırasında, yığının altındaki bir örtülü sıfır açık bir sıfır olur.

1     Append 1 to the implicit empty string on top of the stack
i     Get input n
t&w   Repeat outer loop that many times (push return address n-1 times)
q     Get tape position (initially zero)
]     Move right on tape
&w    On iteration k, push this return address k-1 times
      The following inner loop is run once for each entry in the next row
.     Duplicate top of stack (the last number calculated so far)
q,    Move the entry k spaces down to the top of the stack: this is the appropriate entry
      in the previous row, or (usually) an implicit zero if we're in the first column
+     Add these two numbers
k     Return to pushed address: this statement serves as the end of two loops simultaneously
2:    Divide by two: see below
o     Output as string
@     Terminate

İlk iterasyon, istifin üst kısmındaki gerekli 1'e rağmen, ilk istif derinliğini sıfır olarak kabul eder. Sonuç olarak, 1 kendiliğinden eklenir ve tüm üçgen 2 ile çarpılır. Nihai sonucun 2'ye bölünmesi doğru cevabı verir.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.