O número da partição de um número inteiro positivo é definido como o número de maneiras pelas quais ele pode ser expresso como uma soma de números inteiros positivos. Em outras palavras, o número de partições inteiras que possui. Por exemplo, o número 4
tem as seguintes partições:
[[1, 1, 1, 1], [1, 1, 2], [1, 3], [2, 2], [4]]
Por isso, possui 5
partições. Este é OEIS A000041 .
Tarefa
Dado um número inteiro positivo N, determine seu número de partição.
Todas as regras padrão se aplicam.
A entrada e a saída podem ser tratadas por qualquer média razoável.
Isso é código-golfe , então o código mais curto em bytes vence.
Casos de teste
Entrada | Resultado 1 | 1 2 2 3 3 4 5 5 7 6 11 7 15 8 22 9 30 10 42.
code-golf
math
number-theory
combinatorics
integer-partitions
Martin Ender
fonte
fonte
Respostas:
Pitão , 3 bytes
Experimente aqui! ou Experimente um conjunto de teste.
A resposta levou muito mais tempo para formatar do que escrever o código em si: P.
Quão?
Pyth é a ferramenta certa para o trabalho.
fonte
Mathematica, 11 bytes
Explicação
fonte
Python 2 ,
8583 bytes-2 bytes graças a @notjagan
Experimente online!
Usando fórmula recursiva do OEIS A000041 .
fonte
==0
é equivalente a<1
neste caso. : EDIT abordagem Uso de notjagan<1
vez de==0
, mas o código TIO não.Emojicode 0.5,
204201 bytesExperimente online!
-3 bytes usando "menor que ou igual a 1" em vez de "menor que 2" porque o emoji "menor que" possui uma codificação UTF-8 bastante longa. Também feito
t
congelou para silenciar um aviso sem afetar a contagem de bytes.Estende a classe integ (número inteiro) com um método chamado 🅰️. Você pode escrever um programa simples que pega um número da entrada, chama 🅰️ no número e imprime o resultado assim:
Esta parte pode ser muito jogada por omitir as mensagens e o tratamento de erros, mas não está incluída na pontuação, então prefiro mostrar mais recursos do Emojicode, melhorando a legibilidade ao longo do caminho.
Ungolfed
Explicação
Nota: muitas opções de emoji não fazem muito sentido no emojicode 0.5. É 0.x, afinal. 0,6 corrigirá isso.
O Emojicode é uma linguagem de programação orientada a objetos com genéricos, protocolos, opcionais e fechamentos, mas este programa não usa fechamentos e todos os genéricos e protocolos podem ser considerados implícitos, enquanto a única opção aparece no stub de E / S.
O programa opera em apenas alguns tipos: 🚂 é o tipo inteiro, 🔡 é o tipo de string e ⏩ é o tipo de faixa. Alguns booleanos (👌) também aparecem, mas são usados apenas em condições. Os booleanos podem assumir um valor de 👍 ou 👎, que corresponde a verdadeiro e falso, respectivamente.
Atualmente, não há operadores no Emojicode, portanto, adição, comparsões e outras operações que normalmente são operadores são implementadas como funções, fazendo com que as expressões usem a notação de prefixo. . Os operadores também estão planejados em 0,6.
Vamos abordar o programa de teste primeiro.
Este é o bloco,, que pode ser comparado ao main de outros idiomas.
Uvas e melancias declaram blocos de código no emojicode.
Isso declara um nome "congelado"
str
e define seu valor como uma nova sequência criada usando o inicializador (construtor) 😯, que recebe um prompt como uma sequência e depois insere uma linha do usuário. Por que usar um congelado em vez de uma variável? Como não muda, uma variável emitirá um aviso.Vamos dividir.
🚂str 10
chama o método on nostr
congelado com o argumento 10. Por convenção, os métodos nomeados com o nome de um tipo convertem o objeto nesse tipo. 10 é a base a ser usada para conversão de número inteiro. Este método retorna um opcional, significa: avaliar a expressão. Se o opcional contiver nada, a condição será avaliada como 👎 (falso). Caso contrário, um nome congelado é criado com o valor desembrulhado do opcional e a condição é avaliada como 👍, (verdadeiro). Portanto, no uso normal, o bloco após a condicional é inserido.🍬🚂
,. Os opcionais podem conter um valor do tipo base ou do nada, ⚡. Quando a string não contém um número, ⚡ é retornado. Para usar o valor, é necessário desembrulhar o opcional usando 🍺, o que gera um erro de tempo de execução se o valor for ⚡. Portanto, é uma boa prática verificar o nada antes de desembrulhar um opcional. É tão comum, de fato, que o Emojicode tenha uma abreviação para isso. Normalmente,🍊
é um "se".🍊🍦 variable expression
variable
🍇 ... 🍉
🅰️ é o método que o código principal adiciona a 🚂 usando 🐋 que calcula o número de partições. Isso chama 🅰️ no
num
congelado que declaramos no condicional e converte o resultado em uma string usando a base 10 pelo método 🔡. Então, 😀 imprime o resultado.🍓 significa "else", portanto esse bloco é inserido quando o usuário não digitou um número corretamente.
Imprime a string literal.
Agora, vejamos o programa principal. Eu vou explicar a versão não destruída; a versão golfed acabou de remover o espaço em branco e as variáveis renomeadas para nomes de letras únicas.
Estenda a classe.. Esse é um recurso que não é comumente encontrado em linguagens de programação. Em vez de criar uma nova classe com 🚂 como superclasse, ifies modifica 🚂 diretamente.
Cria um novo método chamado that️ que retorna a 🚂. Retorna o número de partições calculadas usando a fórmula
a(n) = (1/n) * Sum_{k=0..n-1} sigma(n-k)*a(k)
🐕 é semelhante a
this
ouself
de outras línguas e refere-se ao objeto em que o método foi chamado. Essa implementação é recursiva, portanto, esta é a condição final: se o número em que o método foi chamado for menor ou igual a 1, retorne 1.Crie uma nova variável
sum
e defina-a como 0. Assume implicitamente o tipo 🚂.🔂 itera sobre qualquer coisa que implemente o protocolo 🔂🐚⚪️, enquanto ⏩ é um literal de intervalo que implementa 🔂🐚🚂. Um intervalo possui um valor inicial, um valor de parada e um valor de etapa, que é assumido como 1 se
start < stop
, ou -1, caso contrário. Também é possível especificar o valor da etapa usando ⏭ para criar o literal do intervalo. O valor inicial é inclusivo, enquanto o valor de parada é exclusivo, portanto isso é equivalente afor k in range(n)
ouSum_{k=0..n-1}
na fórmula.Precisamos calcular sigma (n - k), ou a soma dos divisores de
n - k
em outras palavras, e o argumento é necessário algumas vezes, portanto, isso armazenan - k
na variávelnmk
para salvar alguns bytes.Isso define a
sig
variável para o argumento de sigma e itera sobre todos os números de 1 anmk - 1
. Eu poderia inicializar a variável para 0 e repetir 1..nmk, mas fazê-lo dessa maneira é mais curto.🚮 calcula o restante, ou módulo e 😛 verifica a igualdade; portanto, a condição será 👍 se
i
for um divisor denmk
.Essa é uma tarefa por chamada, semelhante à
+= -= >>=
família de operadores em alguns dos idiomas inferiores sem emoji. Esta linha também pode ser escrita como🍮 sig ➕ sig i
. Portanto, depois que o loop interno terminar,sig
ele conterá a soma dos divisores den - k
, ousigma(n - k)
Outra atribuição por chamada, portanto, isso adiciona
sigma(n - k) * A(k)
ao total, assim como na fórmula.Finalmente, a soma é dividida por n e o quociente é retornado. Essa explicação provavelmente levou três vezes mais tempo do que escrever o próprio código ...
fonte
Pari / GP , 8 bytes
Experimente online!
fonte
Oitava, 18 bytes
Usa a função interna partcnt.
Não é possível acertar usando uma função anônima usando @, alguma ajuda seria apreciada.
fonte
Retina , 34 bytes
Experimente online!
Explicação
Converta a entrada para unário.
Isso calcula todas as 2 partições n-1 da lista de dígitos unários. Fazemos isso repetidamente (
+
) correspondendo repetidamente ( ) ao primeiro (1
) limite de não palavra (\B
ou seja, uma posição entre dois1
s) em cada linha (%
) e substituindo-o por;
, tudo depois dele ($'
), um avanço de linha (¶
), tudo à frente de ($`
) e,
. Exemplo:Torna-se
Onde
v
marca o resultado$'
e^
marca o resultado$`
. Esse é um idioma comum para obter o resultado de duas substituições diferentes ao mesmo tempo (basicamente inserimos;
a,
substituição e a substituição, bem como as "metades" ausentes da string para concluir duas substituições completas).Trataremos
;
como partições reais e,
apenas como espaços reservados que impedem a\B
correspondência subseqüente . Então próximo ...... removemos essas vírgulas. Isso nos dá todas as partições. Por exemplo, para entrada
4
, obtemos:No entanto, não nos preocupamos com o pedido:
Isso classifica as execuções de
1
s em cada linha, para obter partições não ordenadas.Finalmente, contamos as correspondências únicas (
@
) de.+
, ou seja, quantas linhas / partições distintas obtivemos. Eu adicionei essa@
opção há muito tempo, esqueci completamente e só a redescobri recentemente. Nesse caso, ele salva um byte na primeira desduplicação das linhasD`
.fonte
Python 2 ,
5453 bytesExperimente online!
Como funciona
Cada partição de n pode ser representada como uma lista x = [x 1 , ⋯, x m ] de modo que x 1 + ⋯ + x m = n . Essa representação se torna única se exigirmos que x 1 ≤ ⋯ ≤ x m .
Definimos uma função auxiliar f (n, k) que conta as partições com o limite inferior k , ou seja, as listas x tais que x 1 + ⋯ + x m = n e k ≤ x 1 ≤ ⋯ ≤ x m . Para a entrada n , o desafio pede a saída de f (n, 1) .
Para números inteiros positivos n e k tais que k ≤ n , há pelo menos uma partição com o limite inferior k : a lista de singleton [n] . Se n = k (em particular, se n = 1 ), esta é a única partição qualificada. Por outro lado, se k> n , não há soluções.
Se k <n , podemos contar recursivamente as partições restantes construindo-as da esquerda para a direita, da seguinte maneira. Para cada j tal que k ≤ j ≤ n / 2 , podemos construir partições [x 1 , ⋯, x m ] = [j, y 1 , ⋯, y m-1 ] . Temos que x 1 + ⋯ + x m = n se e somente se y 1 + ⋯ + y m-1 = n - j . Além disso, x 1 ≤ ⋯ ≤ x m se e somente se j ≤ y 1 ≤ ⋯ y m-1 .
Portanto, as partições x de n que começam com j podem ser calculadas como f (n - j, j) , que conta as partições válidas y . Ao exigir que j ≤ n / 2 , garantimos que j ≤ n - j , para que haja pelo menos um y . Podemos assim contar todas as partições de n somando 1 (para [n] ) ef (n - j, j) para todos os valores válidos de j .
O código é uma implementação direta da função matemática f . Além disso, ele faz k padrão para 1 , então
f(n)
calcula o valor de f (n, 1) para a entrada n .fonte
J ,
3735 bytesExperimente online!
Explicação
fonte
p(n) = sum(sigma(n-k) * p(k) for k = 0 to n-1) / n
. Adicionarei uma explicação do código mais tarde, quando achar que não pode ser reduzido significativamente.JavaScript,
125121 bytesExperimente online!
Aviso: a complexidade do tempo e do espaço é exponencial. Funciona muito devagar para grandes números.
fonte
Python 2 , 89 bytes
-9 bytes por Mr.Xcoder -1 byte por notjagan
Experimente online!
fonte
¯\_(ツ)_/¯
- BTW, se você quiser mantê-lo uma função completa, você não precisa a variável, 94 bytesGelatina , 13 bytes
Experimente online!
Leva 5 segundos para resolver n = 1000 no TIO.
fonte
Java 8 (229 bytes)
Ungolfed:
fonte
Gelatina , 3 bytes
O
Œṗ
átomo foi adicionado recentemente e significa "Partições inteiras".Experimente online!
fonte
Pyt , 2 bytes
Explicação:
fonte
JavaScript ES7, 69 bytes
JavaScript ES6, 71 bytes
Complexidade temporal O (n ^ n), portanto, tenha cuidado (um atraso óbvio aparece no meu computador por
F(6)
)fonte