Emita o n-ésimo número da campainha


13

Um número de campainha ( OEIS A000110 ) é o número de maneiras de particionar um conjunto de n elementos rotulados (distintos). O número 0 da campainha é definido como 1.

Vejamos alguns exemplos (eu uso colchetes para denotar os subconjuntos e chaves para as partições):

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

Existem muitas maneiras de calcular os números de campainha e você pode usar qualquer um deles. Uma maneira será descrita aqui:

A maneira mais fácil de calcular os números de Bell é usar um triângulo numérico semelhante ao triângulo de Pascal para os coeficientes binomiais. Os números dos sinos aparecem nas bordas do triângulo. Começando com 1, cada nova linha no triângulo é construída tomando a última entrada na linha anterior como a primeira entrada e definindo cada nova entrada para o vizinho esquerdo mais o vizinho superior esquerdo:

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

Você pode usar indexação 0 ou indexação 1. Se você usar a indexação 0, uma entrada de 3deve sair 5, mas deve sair 2se você usar a indexação 1.

Seu programa deve trabalhar até o número 15 da Bell, emitindo 1382958545. Em teoria, seu programa deve ser capaz de lidar com números maiores (em outras palavras, não codifique as soluções). EDIT: você não precisa lidar com uma entrada de 0 (para indexação 0) ou 1 (para indexação 1) porque não é calculada pelo método do triângulo.

Casos de teste (assumindo a indexação 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

As respostas que usam um método interno (como BellB [n] na Wolfram Language) que produz diretamente números de Bell não serão competitivas.

O código mais curto (em bytes) vence.


Se você usar 0 indexação, uma entrada de 3saída deve5 Seria ouput 15, certo? E com 1-indexação seria de saída5
Luis Mendo

O raciocínio por trás disso estava contando o 0º número de campainha como índice 0 na indexação 0 e índice 1 na indexação 1. Seu caminho pode ser mais claro, mas as respostas existentes funcionam assim, então não posso mudar isso agora. Acabei de ingressar neste site há algumas horas
manipulada

Mas você diz que, com a indexação 1, a entrada 3deve sair 2. Então, o que a entrada 1daria com a indexação 1?
Luis Mendo

1 -> 1, 2 -> 1, 3 -> 2 (correspondente aos números 0, 1 e 2 de campainha), em oposição a 0 -> 1, 1 -> 1, 2 -> 2 Talvez eu esteja usando o errado terminologia
manipulada

Eu acho que entendi. O primeiro 1 está faltando em sua tabela de exemplo e de saída, que me confundiu
Luis Mendo

Respostas:


2

Geléia , 9 bytes

ṖµṀcæ.߀‘

Isso usa a fórmula

Fórmula

que é fechado sempre que n <2 .

Experimente online!

Como funciona

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

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

O primeiro é indexado a 0, o segundo é indexado a 1.


8

Haskell, 36 bytes

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

Usa o método triângulo, manipula corretamente 0, 0 com base.



4

Mathematica, 24 bytes

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

-13 bytes de @Kelly Lowder!


Sum[k^#/k!,{k,0,∞}]/E&é apenas 24 bytes #
Kelly Lowder

3

Geléia , 14 12 11 bytes

ṫ0;⁸+\
1Ç¡Ḣ

Experimente online!

Não atingiu exatamente os pontos fortes do Jelly com entrada dinâmica ¡, sempre modificando a matriz e a falta de um átomo precedente (um byte ;@ou reverso ).


3

CJam (19 bytes)

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

Demonstração online

Dissecação

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 bytes

:dtEw1Zh1Ze/Yo

A entrada é baseada em 0. Experimente online!

Explicação

Isso usa a fórmula

insira a descrição da imagem aqui

onde p F q ( a 1 , ..., a p ; b 1 , ..., b q ; x ) é a função hipergeométrica generalizada .

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

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

Experimente online!

A fórmula recursiva vem da colocação de nelementos em partições. Para cada elemento, por sua vez, decidimos se deve colocá-lo:

  • Em uma partição existente, da qual existem kopções
  • Para iniciar uma nova partição, o que aumenta o número de opções kpara elementos futuros

De qualquer maneira, diminui o número restante nde elementos a serem colocados. Portanto, temos a fórmula recursiva f(n,k)=k*f(n-1,k)+f(n-1,k+1)e f(0,k)=1, com f(n,0)o n-ésimo número de Bell.


2

Python 2 , 91 bytes

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

Experimente online!

B (n) calculado como uma soma dos números de Stirling do segundo tipo.


Essa é uma boa solução. Observe que o uso de números embutidos para Stirling do segundo tipo poderia computar os números de Bell (se estiver usando o Mathematica ou similar)
manipulado em

Você pode salvar dois bytes diretamente na definição de s: como as chamadas recursivas sempre diminuem ne não há divisão pork você pode perder o *kno primeiro período.
Peter Taylor

Ou você pode salvar um monte achatando em um lambda, trabalhando em linhas inteiras: 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

como sua função Bnão é recursiva e é sua resposta final, você pode omitir o B=para salvar 2 bytes
Felipe Nardi Batista

2

MATLAB, 128 103 bytes

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)

Bastante auto-explicativo. Omitir um ponto e vírgula no final de uma linha imprime o resultado.

25 bytes salvos graças a Luis Mendo.




2

Ohm , 15 bytes

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

Experimente online!

Usa o forumla de Dobinski (funciona mesmo para B (0) yay ).

Explicação

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

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]

Demonstração online no Python 2, mas também funciona no Python 3.

Isso cria o triângulo de Aitken usando uma lambda recursiva para um loop de golfe.



1

J, 17 bytes

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

Usa o método de cálculo do triângulo.

Experimente online!

Explicação

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 bytes

Construção recursiva simples do triângulo, mas é extremamente ineficiente para fins práticos. O cálculo do número da 15ª campainha faz com que o tempo limite do TIO seja excedido, mas funciona na minha máquina.

Isso usa a indexação 1 e retorna em Truevez 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)

Experimente online!


Obrigado a @FelipeNardiBatista por salvar 8 bytes!


60 bytes . retornando booleanos em vez de números (0,1) é aceitável em python
Felipe Nardi Batista

1

PHP , 72 bytes

função recursiva indexada 1

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

Experimente online!

PHP , 86 bytes

Indexado a 0

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

Experimente online!

PHP , 89 bytes

função recursiva indexada em 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;}

Experimente online!


1

Alice , 22 bytes

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

Experimente online!

Isso usa o método do triângulo. Para n = 0, calcula B (1), que é convenientemente igual a B (0).

Explicação

Este é um modelo padrão para programas que recebem entradas no modo ordinal, processam no modo cardinal e produzem o resultado no modo ordinal. UMA1 foi adicionado ao modelo para colocar esse valor na pilha abaixo da entrada.

O programa usa a pilha como uma fila circular em expansão para calcular cada linha do triângulo. Durante cada iteração após a primeira, um zero implícito abaixo da pilha se torna um zero explícito.

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

A primeira iteração assume efetivamente uma profundidade inicial da pilha igual a zero, apesar do 1 necessário no topo da pilha. Como resultado, o 1 acaba sendo adicionado a si mesmo e o triângulo inteiro é multiplicado por 2. Dividir o resultado final por 2 fornece a resposta correta.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.