Emette l'ennesimo numero di campana


13

Un numero di Bell ( OEIS A000110 ) è il numero di modi per partizionare un set di n elementi (distinti) etichettati. Il numero 0 Bell è definito come 1.

Diamo un'occhiata ad alcuni esempi (uso parentesi per indicare i sottoinsiemi e le parentesi graffe per le partizioni):

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

Esistono molti modi per calcolare i numeri Bell e sei libero di usarli. Un modo sarà descritto qui:

Il modo più semplice per calcolare i numeri di Bell è usare un triangolo numerico simile al triangolo di Pascal per i coefficienti binomiali. I numeri di Bell appaiono sui bordi del triangolo. A partire da 1, ogni nuova riga nel triangolo viene costruita prendendo l'ultima voce della riga precedente come prima voce, quindi impostando ciascuna nuova voce sul suo vicino sinistro più il suo vicino superiore sinistro:

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

È possibile utilizzare 0-indicizzazione o 1-indicizzazione. Se si utilizza l'indicizzazione 0, viene immesso un input di 3dovrebbe 5, ma dovrebbe essere emesso 2se si utilizza l'indicizzazione 1.

Il tuo programma deve funzionare fino al 15 ° numero Bell, in uscita 1382958545. In teoria, il tuo programma dovrebbe essere in grado di gestire numeri più grandi (in altre parole, non codificare le soluzioni). EDIT: non è necessario gestire un input di 0 (per 0-indicizzazione) o 1 (per 1-indicizzazione) perché non è calcolato dal metodo del triangolo.

Casi di test (presupponendo 0-indicizzazione):

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

Le risposte che utilizzano un metodo integrato (come BellB [n] nella lingua di Wolfram) che produce direttamente numeri di Bell non saranno competitive.

Il codice più breve (in byte) vince.


Se utilizzi l'indicizzazione 0, un input di 3dovrebbe essere output5 Sarebbe uscito 15, giusto? E con l'indicizzazione 1 avrebbe prodotto5
Luis Mendo il

Il ragionamento alla base di ciò era il conteggio del numero della campana 0 come indice 0 nell'indicizzazione 0 e indice 1 nell'indicizzazione 1. La tua strada potrebbe essere più chiara, ma le risposte esistenti funzionano così, quindi non posso cambiarlo ora. Sono appena entrato in questo sito poche ore fa
truccato il

Ma tu dici che con l'indicizzazione 1, l'input 3dovrebbe essere generato 2. Quindi cosa darebbe l'input 1con l'indicizzazione 1?
Luis Mendo,

1 -> 1, 2 -> 1, 3 -> 2 (corrispondenti ai numeri 0th, 1st e 2nd Bell) anziché 0 -> 1, 1 -> 1, 2 -> 2 Forse sto usando qualcosa di sbagliato terminologia
truccata il

Penso di averlo capito. Il primo 1 manca nella tabella di esempio e nell'output, il che mi ha confuso
Luis Mendo,

Risposte:


2

Gelatina , 9 byte

ṖµṀcæ.߀‘

Questo utilizza la formula

formula

che viene chiuso ogni volta che n <2 .

Provalo online!

Come funziona

ṖµṀ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 byte

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

Il primo è 0-indicizzato, il secondo è 1-indicizzato.


8

Haskell, 36 byte

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

Utilizza il metodo triangolo, gestisce correttamente 0, basato su 0.



4

Mathematica, 24 byte

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

-13 byte da @Kelly Lowder!


Sum[k^#/k!,{k,0,∞}]/E&è solo 24 byte
Kelly Lowder

3

Gelatina , 14 12 11 byte

ṫ0;⁸+\
1Ç¡Ḣ

Provalo online!

Non ha colpito esattamente i punti di forza di Jelly con un input dinamico ¡, modificando sempre l'array e la mancanza di un atomo prependente (un byte ;@o reverse ).


3

CJam (19 byte)

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

Demo online

Dissezione

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 byte

:dtEw1Zh1Ze/Yo

L'input è basato su 0. Provalo online!

Spiegazione

Questo utilizza la formula

enter image description here

dove p F q ( a 1 , ..., a p ; b 1 , ..., b q ; x ) è la funzione ipergeometrica generalizzata .

:      % 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 byte

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

Provalo online!

La formula ricorsiva deriva dal posizionamento di nelementi in partizioni. Per ogni elemento a sua volta, decidiamo se posizionarlo:

  • In una partizione esistente, di cui esistono kscelte
  • Per avviare una nuova partizione, che aumenta il numero di scelte kper gli elementi futuri

In entrambi i casi diminuisce il numero rimanente ndi elementi da posizionare. Quindi, abbiamo la formula ricorsiva f(n,k)=k*f(n-1,k)+f(n-1,k+1)e f(0,k)=1, con f(n,0)l'ennesimo numero di Bell.


2

Python 2 , 91 byte

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

Provalo online!

B (n) calcolato come somma dei numeri di Stirling del secondo tipo.


Questa è una bella soluzione. Si noti che l'utilizzo di un built-in per i numeri di Stirling del secondo tipo consentirebbe di calcolare i numeri Bell (se si utilizza Mathematica o simile)
truccato il

Puoi salvare due byte direttamente nella definizione di s: poiché le chiamate ricorsive si riducono sempre ne non c'è divisione per kte, puoi perdere *kil primo termine.
Peter Taylor,

Oppure puoi salvare un gruppo appiattendolo in un lambda, lavorando su intere file: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,

poiché la tua funzione Bnon è ricorsiva ed è la tua risposta finale, puoi ometterla B=per salvare 2 byte
Felipe Nardi Batista

2

MATLAB, 128 103 byte

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)

Abbastanza esplicativo. Se si omette un punto e virgola alla fine di una riga, il risultato viene stampato.

25 byte salvati grazie a Luis Mendo.




2

Ohm , 15 byte

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

Provalo online!

Utilizza il forumla di Dobinski (funziona anche con B (0) yay ).

Spiegazione

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

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]

Demo online in Python 2, ma funziona anche in Python 3.

Questo costruisce il triangolo di Aitken usando un lambda ricorsivo per un circuito da golf.



1

J, 17 byte

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

Utilizza il metodo di calcolo del triangolo.

Provalo online!

Spiegazione

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 , 78 byte

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

Ho deciso di provare a percorrere una strada diversa per il calcolo. Questo utilizza la formula di Dobinski, indicizzata 0, non funziona per 0.

Provalo online!


1
poiché la tua funzione fnon è ricorsiva, puoi omettere f=e salvare 2 byte
Felipe Nardi Batista

1

Python 3 , 68 60 byte

Semplice costruzione ricorsiva del triangolo, ma è selvaggiamente inefficiente per scopi pratici. Il calcolo fino al 15 ° numero Bell provoca il timeout di TIO, ma funziona sulla mia macchina.

Questo utilizza 1-indicizzazione e restituisce Trueinvece di 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)

Provalo online!


Grazie a @FelipeNardiBatista per aver salvato 8 byte!


60 byte . restituire i valori booleani anziché i numeri (0,1) è accettabile in pitone
Felipe Nardi Batista

1

PHP , 72 byte

funzione ricorsiva indicizzata 1

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

Provalo online!

PHP , 86 byte

0-indicizzato

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

Provalo online!

PHP , 89 byte

funzione ricorsiva indicizzata 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;}

Provalo online!


1

Alice , 22 byte

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

Provalo online!

Questo utilizza il metodo del triangolo. Per n = 0, calcola invece B (1), che è convenientemente uguale a B (0).

Spiegazione

Questo è un modello standard per i programmi che accettano input in modalità ordinale, lo elaborano in modalità cardinale e producono il risultato in modalità ordinale. UN1 è stato aggiunto al modello per mettere quel valore nello stack sotto l'input.

Il programma utilizza lo stack come una coda circolare in espansione per calcolare ogni riga del triangolo. Durante ogni iterazione oltre il primo, uno zero implicito sotto lo stack diventa uno zero esplicito.

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 prima iterazione assume effettivamente una profondità iniziale dello stack pari a zero, nonostante 1 richiesto nella parte superiore dello stack. Di conseguenza, l'1 finisce per essere aggiunto a se stesso e l'intero triangolo viene moltiplicato per 2. Dividendo il risultato finale per 2 si ottiene la risposta corretta.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.