Sortie du nième numéro de sonnerie

13

UNE numéro de Bell ( OEIS A000110 ) est le nombre de façons de partitionner un ensemble de n éléments (distincts) étiquetés. Le 0e numéro de Bell est défini comme 1.

Regardons quelques exemples (j'utilise des crochets pour désigner les sous-ensembles et les accolades pour les partitions):

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

Il y a plusieurs façons de calculer les numéros de Bell, et vous êtes libre d'utiliser n'importe lequel d'entre eux. Une façon sera décrite ici:

La façon la plus simple de calculer les nombres de Bell est d'utiliser un triangle numérique ressemblant au triangle de Pascal pour les coefficients binomiaux. Les numéros de Bell apparaissent sur les bords du triangle. En commençant par 1, chaque nouvelle ligne du triangle est construite en prenant la dernière entrée de la ligne précédente comme première entrée, puis en définissant chaque nouvelle entrée sur son voisin gauche plus son voisin supérieur gauche:

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

Vous pouvez utiliser l'indexation 0 ou l'indexation 1. Si vous utilisez l'indexation 0, une entrée de 3devrait sortir 5, mais devrait sortir 2si vous utilisez l'indexation 1.

Votre programme doit fonctionner jusqu'au 15e numéro de Bell, produisant 1382958545 . En théorie, votre programme devrait être capable de gérer de plus grands nombres (en d'autres termes, ne codez pas en dur les solutions). EDIT: vous n'êtes pas obligé de gérer une entrée de 0 (pour l'indexation 0) ou 1 (pour l'indexation 1) car elle n'est pas calculée par la méthode du triangle.

Cas de test (en supposant une indexation 0):

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

Les réponses utilisant une méthode intégrée (comme BellB [n] dans le Wolfram Language) qui produisent directement des numéros de Bell ne seront pas compétitives.

Le code le plus court (en octets) gagne.

gréé
la source
Si vous utilisez l'indexation 0, une entrée de 3devrait sortir5 Elle sortirait 15, non? Et avec l'indexation 1, cela produirait5
Luis Mendo
Le raisonnement derrière cela comptait le numéro de la 0e cloche comme l'index 0 dans l'indexation 0 et l'index 1 dans l'indexation 1. Votre chemin est peut-être plus clair, mais les réponses existantes fonctionnent comme ça, donc je ne peux pas le changer maintenant. Je viens de rejoindre ce site il y a quelques heures
truqué le
Mais vous dites qu'avec 1-indexation, l'entrée 3devrait sortir 2. Que donnerait alors l'entrée 1avec l'indexation 1?
Luis Mendo
1 -> 1, 2 -> 1, 3 -> 2 (correspondant aux 0e, 1er et 2e numéros de Bell) par opposition à 0 -> 1, 1 -> 1, 2 -> 2 Peut-être que j'utilise le mauvais terminologie
truqué le
Je pense que je comprends. Le premier 1 est manquant dans votre exemple de tableau et de sortie, ce qui m'a dérouté
Luis Mendo

Réponses:

2

Gelée , 9 octets

ṖµṀcæ.߀‘

Cela utilise la formule

formula

qui est fermé chaque fois que n <2 .

Essayez-le en ligne!

Comment ça fonctionne

ṖµṀ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.
Dennis
la source
8

JavaScript (ES6), 47 octets

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

Le premier est indexé 0, le second est indexé 1.

Neil
la source
8

Haskell, 36 octets

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

Utilise la méthode du triangle, gère correctement la base 0, 0.

Christian Sievers
la source
5

R , 31 octets

sum(gmp::Stirling2.all(scan()))

utilise le numéro de Stirling du deuxième type et calcule ces nombres avec le package gmp ; lit à partir de stdin et renvoie la valeur sous forme de grand entier; échoue pour 0; 1 indexé.

Giuseppe
la source
4

Mathematica, 24 octets

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

-13 octets de @Kelly Lowder!

J42161217
la source
Sum[k^#/k!,{k,0,∞}]/E&n'est que de 24 octets
Kelly Lowder
3

Gelée , 14 12 11 octets

ṫ0;⁸+\
1Ç¡Ḣ

Essayez-le en ligne!

N'a pas touché exactement les points forts de Jelly avec une entrée dynamique dans ¡, modifiant toujours le tableau et l'absence d'atome en attente (un octet ;@ou inversé ).

PurkkaKoodari
la source
3

CJam (19 octets)

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

Démo en ligne

Dissection

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
Peter Taylor
la source
3

MATL , 14 octets

:dtEw1Zh1Ze/Yo

L'entrée est basée sur 0. Essayez-le en ligne!

Explication

Cela utilise la formule

enter image description here

p F q ( a 1 , ..., a p ; b 1 , ..., b q ; x ) est la fonction hypergéométrique généralisée .

:      % 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
Luis Mendo
la source
3

Python , 42 octets

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

Essayez-le en ligne!

La formule récursive vient du placement d' néléments dans des partitions. Pour chaque élément tour à tour, nous décidons de le placer:

  • Dans une partition existante, parmi laquelle il existe des kchoix
  • Pour démarrer une nouvelle partition, ce qui augmente le nombre de choix kpour les éléments futurs

Dans les deux cas, le nombre nd'éléments à placer diminue . Donc, nous avons la formule récursive f(n,k)=k*f(n-1,k)+f(n-1,k+1)et f(0,k)=1, avec f(n,0)le n-ième numéro de Bell.

xnor
la source
2

Python 2 , 91 octets

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

Essayez-le en ligne!

B (n) calculé comme une somme de nombres de Stirling du deuxième type.

Chas Brown
la source
Voilà une bonne solution. Notez que l'utilisation d'un numéro intégré pour les numéros de Stirling du deuxième type serait autorisée à calculer les numéros de Bell (si vous utilisez Mathematica ou similaire)
truqué le
Vous pouvez enregistrer deux octets directement dans la définition de s: puisque les appels récursifs diminuent toujours net qu'il n'y a pas de division par kvous pouvez perdre le *kdans le premier terme.
Peter Taylor
Ou vous pouvez enregistrer un tas en s'aplatissant en un lambda, en travaillant sur des rangées entières: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
comme votre fonction Bn'est pas récursive et qu'il s'agit de votre réponse finale, vous pouvez omettre B=d' enregistrer 2 octets
Felipe Nardi Batista
2

MATLAB, 128 103 octets

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)

Assez explicite. L'omission d'un point-virgule à la fin d'une ligne imprime le résultat.

25 octets enregistrés grâce à Luis Mendo.

gréé
la source
2

R , 46 octets

r=1;for(i in 1:scan())r=cumsum(c(r[i],r));r[1]

Essayez-le en ligne!

Leaky Nun
la source
42 octets - par Tdéfaut TRUE(aka 1) à moins qu'il ne soit défini ailleurs
Giuseppe
2

Ohm , 15 octets

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

Essayez-le en ligne!

Utilise le forumla de Dobinski (fonctionne même pour B (0) yay ).

Explication

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???)
Datboi
la source
2

Python (79 octets)

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]

Démo en ligne en en Python 2, mais elle fonctionne également en Python 3.

Cela construit le triangle d'Aitken en utilisant un lambda récursif pour une boucle de golf.

Peter Taylor
la source
1

J, 17 octets

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

Utilise la méthode de calcul du triangle.

Essayez-le en ligne!

Explication

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)
miles
la source
1

Python 3 , 78 octets

from math import*
f=lambda n:ceil(sum(k**n/e/factorial(k)for k in range(2*n)))

J'ai décidé d'essayer de suivre un itinéraire différent pour le calcul. Cela utilise la formule de Dobinski, indexée 0, ne fonctionne pas pour 0.

Essayez-le en ligne!

C McAvoy
la source
1
comme votre fonction fn'est pas récursive, vous pouvez omettre le f=et enregistrer 2 octets
Felipe Nardi Batista
1

Python 3 , 68 60 octets

Construction récursive simple du triangle, mais il est extrêmement inefficace à des fins pratiques. Le calcul jusqu'au 15e numéro de Bell fait expirer TIO, mais cela fonctionne sur ma machine.

Cela utilise l'indexation 1 et renvoie Trueau lieu de 1.

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

Essayez-le en ligne!


Merci à @FelipeNardiBatista pour avoir économisé 8 octets!

Chase Vogeli
la source
60 octets . renvoyer des booléens au lieu de nombres (0,1) est acceptable en python
Felipe Nardi Batista
1

PHP , 72 octets

fonction récursive indexée 1

function f($r,$c=0){return$r?$c?f($r-1,$c-1)+f($r,$c-1):f($r-1,$r-2):1;}

Essayez-le en ligne!

PHP , 86 octets

0 indexé

for(;$r++<$argn;)for($c=~0;++$c<$r;)$l=$t[$r][$c]=$c?$l+$t[$r-1][$c-1]:($l?:1);echo$l;

Essayez-le en ligne!

PHP , 89 octets

fonction récursive indexée 0

function f($r,$s=NULL){$c=$s??$r-1;return$r>1?$c?f($r-1,$c-1)+f($r,$c-1):f($r-1,$r-2):1;}

Essayez-le en ligne!

Jörg Hülsermann
la source
1

Alice , 22 octets

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

Essayez-le en ligne!

Cela utilise la méthode du triangle. Pour n = 0, cela calcule B (1) à la place, ce qui est commodément égal à B (0).

Explication

Il s'agit d'un modèle standard pour les programmes qui prennent des entrées en mode ordinal, les traitent en mode cardinal et produisent le résultat en mode ordinal. Un 1a été ajouté au modèle pour mettre cette valeur sur la pile sous l'entrée.

Le programme utilise la pile comme une file d'attente circulaire en expansion pour calculer chaque ligne du triangle. Au cours de chaque itération après la première, un zéro implicite sous la pile devient un zéro explicite.

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

La première itération suppose effectivement une profondeur de pile initiale de zéro, malgré le 1 requis en haut de la pile. En conséquence, le 1 finit par s'ajouter à lui-même et le triangle entier est multiplié par 2. La division du résultat final par 2 donne la bonne réponse.

Nitrodon
la source