Quantas partições eu tenho?

16

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 4tem as seguintes partições:

[[1, 1, 1, 1], [1, 1, 2], [1, 3], [2, 2], [4]]

Por isso, possui 5partiçõ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 é , 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.
Martin Ender
fonte
1
Tenho quase certeza esta é uma duplicata ...
DJMcMayhem
@DJMcMayhem Umm, ok. Deixe-me saber se você encontrar uma duplicata. Desculpe, eu sou novo em tudo isso!
1
@DJMcMayhem talvez esta pergunta que você fez desde que é um pequeno passo de "geração" para "contagem", mas você não necessariamente tem que gerar todas as partições de contá-las ...
Giuseppe
1
este é um burro, EXCETO que é um popcon (?) e fechado como muito amplo. IMHO este é muito melhor escrito e deve ser manter em aberto, enquanto o antigo deve ser (reaberto e) fechado como joguete
Rod
2
@ Rod, é um pop-con ruim, mas mudar o motivo mais próximo para enganar não seria uma melhoria. O requisito de desempenho seria um obstáculo para enviar algumas respostas (ninguém vai gerar as partições 24061467864032622473692149727991 de 1000 em alguns minutos); e a implementação de Hardy-Ramanujan-Rademacher não é exatamente um jogo de golfe ... No entanto, pode valer a pena abrir uma discussão na meta sobre o que fazer com essa pergunta e essa.
31417 Peter Peter Taylor

Respostas:

13

Pitão , 3 bytes

l./

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.

Programa completo com entrada implícita.

 ./ Partições inteiras. Retorne todas as listas classificadas de números inteiros positivos adicionadas à entrada.
l comprimento.
      Saída implícita do resultado.
Mr. Xcoder
fonte
34

Mathematica, 11 bytes

PartitionsP

Explicação

¯\_(ツ)_/¯
ngenisis
fonte
8

Python 2 , 85 83 bytes

-2 bytes graças a @notjagan

lambda n:n<1or sum(sum(i*((n-k)%i<1)for i in range(1,n+1))*p(k)for k in range(n))/n

Experimente online!

Usando fórmula recursiva do OEIS A000041 .

shooqie
fonte
83 bytes.
notjagan
84 bytes . ==0é equivalente a <1neste caso. : EDIT abordagem Uso de notjagan
Mr. Xcoder
@ Mr.Xcoder O código original realmente tinha, em <1vez de ==0, mas o código TIO não.
notjagan
Também 83 bytes .
Mr. Xcoder
8

Emojicode 0.5, 204 201 bytes

🐋🚂🍇🐖🅰️➡🚂🍇🍊⬅🐕1🍇🍎1🍉🍮s 0🔂k⏩0🐕🍇🍦t➖🐕k🍮r t🔂i⏩1 t🍇🍊😛🚮t i 0🍇🍮➕r i🍉🍉🍮➕s✖r🅰️k🍉🍎➗s🐕🍉🍉

Experimente 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 feitot 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:

🏁🍇
 🍦str🔷🔡😯🔤Please enter a number🔤
 🍊🍦num🚂str 10🍇
  😀🔡🅰️num 10
 🍉🍓🍇
  😀🔤Learn what a number is, you moron!🔤
 🍉
🍉

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

🐋🚂🍇
 🐖🅰️➡🚂🍇
  🍊◀️🐕2🍇
   🍎1
  🍉
  🍮sum 0
  🔂k⏩0🐕🍇
   🍦nmk➖🐕k
   🍮sig nmk
   🔂i⏩1 nmk🍇
    🍊😛🚮nmk i 0🍇
     🍮➕sig i
    🍉
   🍉
   🍮➕sum✖sig🅰️k
  🍉
  🍎➗sum🐕
 🍉
🍉

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.

🍦str🔷🔡😯🔤Please enter a number🔤

Isso declara um nome "congelado" stre 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.

🍊🍦num🚂str 10

Vamos dividir. 🚂str 10chama o método on no strcongelado 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 expressionvariable🍇 ... 🍉

😀🔡🅰️num 10

🅰️ é o método que o código principal adiciona a 🚂 usando 🐋 que calcula o número de partições. Isso chama 🅰️ no numcongelado 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.

😀🔤Learn what a number is, you moron!🔤

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órmulaa(n) = (1/n) * Sum_{k=0..n-1} sigma(n-k)*a(k)

🍊⬅🐕1🍇
 🍎1
🍉

🐕 é semelhante a thisou selfde 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.

🍮sum 0

Crie uma nova variável sume defina-a como 0. Assume implicitamente o tipo 🚂.

🔂k⏩0🐕

🔂 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 a for k in range(n)ou Sum_{k=0..n-1}na fórmula.

🍦nmk➖🐕k

Precisamos calcular sigma (n - k), ou a soma dos divisores de n - kem outras palavras, e o argumento é necessário algumas vezes, portanto, isso armazena n - kna variável nmkpara salvar alguns bytes.

🍮sig nmk
🔂i⏩1 nmk

Isso define a sigvariável para o argumento de sigma e itera sobre todos os números de 1 a nmk - 1. Eu poderia inicializar a variável para 0 e repetir 1..nmk, mas fazê-lo dessa maneira é mais curto.

🍊😛🚮nmk i 0

🚮 calcula o restante, ou módulo e 😛 verifica a igualdade; portanto, a condição será 👍 se ifor um divisor de nmk.

🍮➕sig i

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, sigele conterá a soma dos divisores de n - k, ousigma(n - k)

🍮➕sum✖sig🅰️k

Outra atribuição por chamada, portanto, isso adiciona sigma(n - k) * A(k)ao total, assim como na fórmula.

🍎➗sum🐕

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

NieDzejkob
fonte
3

Oitava, 18 bytes

partcnt(input(''))

Usa a função interna partcnt.

Não é possível acertar usando uma função anônima usando @, alguma ajuda seria apreciada.

Michthan
fonte
3

Retina , 34 bytes

.+
$*
+%1`\B
;$'¶$`,
,

%O`1+
@`.+

Experimente online!

Explicação

.+
$*

Converta a entrada para unário.

+%1`\B
;$'¶$`,

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 ( \Bou seja, uma posição entre dois 1s) em cada linha ( %) e substituindo-o por ;, tudo depois dele ( $'), um avanço de linha ( ), tudo à frente de ( $`) e ,. Exemplo:

1;1,111

Torna-se

      vv
1;1,1;11
1;1,1,11
^^^^^

Onde vmarca 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 \Bcorrespondência subseqüente . Então próximo ...

,

... removemos essas vírgulas. Isso nos dá todas as partições. Por exemplo, para entrada 4, obtemos:

1;1;1;1
1;1;11
1;11;1
1;111
11;1;1
11;11
111;1
1111

No entanto, não nos preocupamos com o pedido:

%O`1+

Isso classifica as execuções de 1s 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 linhas D`.

Martin Ender
fonte
3

Python 2 , 54 53 bytes

f=lambda n,k=1:1+sum(f(n-j,j)for j in range(k,n/2+1))

Experimente 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 .

Dennis
fonte
Oh uau, isso é incrível! Você pode adicionar uma explicação sobre como isso funciona?
Eu editei minha resposta. Se alguma coisa não estiver esclarecida, comunique-me por favor.
Dennis
3

J , 37 35 bytes

0{]1&((#.]*>:@#.~/.~&.q:@#\%#),])1:

Experimente online!

Explicação

0{]1&((#.]*>:@#.~/.~&.q:@#\%#),])1:  Input: n
                                 1:  Constant 1
  ]                                  Get n
   1&(                          )    Repeat n times on x = [1]
                          \            For each prefix
                         #               Length
                      q:@                Prime factors
                 /.~&                    Group equal factors
              #.~                        Compute p+p^2+...+p^k for each group
           >:@                           Increment
                    &.q:                 Product
                           %           Divide
                            #          Length
         ]                             Get x
          *                            Times
   1   #.                              Sum
                              ,        Joim
                               ]       Get x
                                       Set this as next value of x
0{                                   Select value at index 0
milhas
fonte
Estou pasmo e pasmo, mente postando uma explicação?
Cole
1
@cole Essa é uma abordagem iterativa que começa com a solução para p (0) = 1 e cria a próxima usando a fórmula 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.
milhas
2

JavaScript, 125 121 bytes

n=>(z=(a,b)=>[...Array(a)].map(b))(++n**n,(_,a)=>z[F=z(n,_=>a%(a/=n,n)|0).sort().join`+`]=b+=eval(F)==n-1&!z[F],b=0)|b||1

Experimente online!

Aviso: a complexidade do tempo e do espaço é exponencial. Funciona muito devagar para grandes números.


fonte
2

Python 2 , 89 bytes

-9 bytes por Mr.Xcoder -1 byte por notjagan

lambda n:len(p(n))
p=lambda n,I=1:{(n,)}|{y+(x,)for x in range(I,n/2+1)for y in p(n-x,x)}

Experimente online!

Gambá morto
fonte
1
90 bytes
Sr. Xcoder
@ Mr.Xcoder Nem sei, por que eu não usei o lambda D:
Dead Possum
Hehe, ¯\_(ツ)_/¯- BTW, se você quiser mantê-lo uma função completa, você não precisa a variável, 94 bytes
Mr. Xcoder
@ Mr.Xcoder Yeah .. Estou me sentindo enferrujado depois de algum tempo longe do codegolf: c
Dead Possum
-1 byte.
notjagan
1

Gelatina , 13 bytes

JÆsæ.:L;
1Ç¡Ḣ

Experimente online!

Leva 5 segundos para resolver n = 1000 no TIO.

milhas
fonte
0

Java 8 (229 bytes)

import java.util.function.*;class A{static int j=0;static BiConsumer<Integer,Integer>f=(n,m)->{if(n==0)j++;else for(int i=Math.min(m,n);i>=1;i--)A.f.accept(n-i,i);};static Function<Integer,Integer>g=n->{f.accept(n,n);return j;};}

Ungolfed:

import java.util.function.*;

class A {
    static int j = 0;
    static BiConsumer<Integer, Integer> f = (n, m) -> {
        if (n == 0)
            j++;
        else
            for (int i = Math.min(m, n); i >= 1; i--)
                A.f.accept(n - i, i);
    };
    static Function<Integer, Integer> g = n -> {
        f.accept(n, n);
        return j;
    };
}
Roberto Graham
fonte
0

Gelatina , 3 bytes

O Œṗátomo foi adicionado recentemente e significa "Partições inteiras".

ŒṗL

Experimente online!

L - Programa completo.

Œṗ - Partições inteiras.
  L - comprimento.
      - Saída implicitamente.
Mr. Xcoder
fonte
0

Pyt , 2 bytes

←ᵱ

Explicação:

←          Get input
 ᵱ         Number of partitions
mudkip201
fonte
0

JavaScript ES7, 69 bytes

n=>(f=(i,s)=>i?[for(c of Array(1+n))f(i-1,s,s-=i)]:c+=!s)(n,n,c=0)&&c

JavaScript ES6, 71 bytes

n=>(f=(i,s)=>i?[...Array(1+n)].map(_=>f(i-1,s,s-=i)):c+=!s)(n,n,c=0)&&c

Complexidade temporal O (n ^ n), portanto, tenha cuidado (um atraso óbvio aparece no meu computador por F(6))

l4m2
fonte